You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gi...@apache.org on 2022/09/22 14:46:42 UTC

[hbase-site] branch asf-site updated: Published site at cc4268a7d2e7a8cc4a092135de32303b64bd55a6.

This is an automated email from the ASF dual-hosted git repository.

git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hbase-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new c16f4601d41 Published site at cc4268a7d2e7a8cc4a092135de32303b64bd55a6.
c16f4601d41 is described below

commit c16f4601d41b07a8f8a1420a877045e444b7ad24
Author: jenkins <bu...@apache.org>
AuthorDate: Thu Sep 22 14:46:24 2022 +0000

    Published site at cc4268a7d2e7a8cc4a092135de32303b64bd55a6.
---
 acid-semantics.html                                |    2 +-
 apache_hbase_reference_guide.pdf                   |    4 +-
 apidocs/constant-values.html                       |   14 +
 apidocs/index-all.html                             |    9 +
 apidocs/org/apache/hadoop/hbase/HConstants.html    |   49 +-
 .../org/apache/hadoop/hbase/util/RegionMover.html  |   30 +-
 .../org/apache/hadoop/hbase/HConstants.html        |   24 +-
 .../org/apache/hadoop/hbase/util/RegionMover.html  | 1605 ++++++++---------
 book.html                                          |    2 +-
 bulk-loads.html                                    |    2 +-
 checkstyle-aggregate.html                          |    8 +-
 checkstyle.rss                                     |   44 +-
 coc.html                                           |    2 +-
 dependencies.html                                  |    2 +-
 dependency-convergence.html                        |    2 +-
 dependency-info.html                               |    2 +-
 dependency-management.html                         |    2 +-
 devapidocs/constant-values.html                    |   14 +
 devapidocs/index-all.html                          |    9 +
 .../org/apache/hadoop/hbase/HBaseServerBase.html   |  104 +-
 devapidocs/org/apache/hadoop/hbase/HConstants.html |   51 +-
 .../apache/hadoop/hbase/backup/package-tree.html   |    6 +-
 .../apache/hadoop/hbase/chaos/package-tree.html    |    2 +-
 .../apache/hadoop/hbase/client/package-tree.html   |   28 +-
 .../hadoop/hbase/coprocessor/package-tree.html     |    2 +-
 .../apache/hadoop/hbase/filter/package-tree.html   |    8 +-
 .../hadoop/hbase/hbtop/terminal/package-tree.html  |    2 +-
 .../org/apache/hadoop/hbase/http/package-tree.html |    2 +-
 .../apache/hadoop/hbase/io/hfile/package-tree.html |    4 +-
 .../org/apache/hadoop/hbase/ipc/package-tree.html  |    2 +-
 .../hadoop/hbase/mapreduce/package-tree.html       |    4 +-
 .../ServerManager.FlushedSequenceIdFlusher.html    |    6 +-
 .../master/ServerManager.ServerLiveState.html      |    8 +-
 .../apache/hadoop/hbase/master/ServerManager.html  |  100 +-
 .../hadoop/hbase/master/balancer/package-tree.html |    2 +-
 .../apache/hadoop/hbase/master/package-tree.html   |    6 +-
 .../hbase/master/procedure/package-tree.html       |    4 +-
 .../hadoop/hbase/monitoring/package-tree.html      |    2 +-
 .../org/apache/hadoop/hbase/package-tree.html      |   22 +-
 .../hadoop/hbase/procedure2/package-tree.html      |    4 +-
 .../apache/hadoop/hbase/quotas/package-tree.html   |    4 +-
 .../hadoop/hbase/regionserver/package-tree.html    |   16 +-
 .../regionserver/querymatcher/package-tree.html    |    2 +-
 .../hbase/regionserver/wal/package-tree.html       |    4 +-
 .../hadoop/hbase/replication/package-tree.html     |    2 +-
 .../replication/regionserver/package-tree.html     |    2 +-
 .../hadoop/hbase/rest/model/package-tree.html      |    2 +-
 .../hadoop/hbase/security/access/package-tree.html |    6 +-
 .../apache/hadoop/hbase/security/package-tree.html |    4 +-
 .../apache/hadoop/hbase/thrift/package-tree.html   |    2 +-
 .../apache/hadoop/hbase/trace/package-tree.html    |    2 +-
 .../hbase/util/RegionMover.RegionMoverBuilder.html |   46 +-
 .../org/apache/hadoop/hbase/util/RegionMover.html  |  102 +-
 .../org/apache/hadoop/hbase/util/package-tree.html |   12 +-
 .../org/apache/hadoop/hbase/HBaseServerBase.html   |  734 ++++----
 .../hbase/HConstants.OperationStatusCode.html      |   24 +-
 .../org/apache/hadoop/hbase/HConstants.html        |   24 +-
 .../ServerManager.FlushedSequenceIdFlusher.html    | 1873 ++++++++++----------
 .../master/ServerManager.ServerLiveState.html      | 1873 ++++++++++----------
 .../apache/hadoop/hbase/master/ServerManager.html  | 1873 ++++++++++----------
 .../hbase/util/RegionMover.RegionMoverBuilder.html | 1605 ++++++++---------
 .../org/apache/hadoop/hbase/util/RegionMover.html  | 1605 ++++++++---------
 downloads.html                                     |    2 +-
 export_control.html                                |    2 +-
 index.html                                         |    2 +-
 issue-management.html                              |    2 +-
 licenses.html                                      |    2 +-
 mailing-lists.html                                 |    2 +-
 metrics.html                                       |    2 +-
 old_news.html                                      |    2 +-
 plugin-management.html                             |    2 +-
 plugins.html                                       |    2 +-
 poweredbyhbase.html                                |    2 +-
 project-info.html                                  |    2 +-
 project-reports.html                               |    2 +-
 pseudo-distributed.html                            |    2 +-
 replication.html                                   |    2 +-
 resources.html                                     |    2 +-
 scm.html                                           |    2 +-
 sponsors.html                                      |    2 +-
 summary.html                                       |    2 +-
 supportingprojects.html                            |    2 +-
 team.html                                          |    2 +-
 testdevapidocs/allclasses-frame.html               |    3 +
 testdevapidocs/allclasses-noframe.html             |    3 +
 testdevapidocs/constant-values.html                |   52 +
 testdevapidocs/index-all.html                      |   70 +
 .../apache/hadoop/hbase/backup/package-tree.html   |    2 +-
 .../hadoop/hbase/class-use/HBaseClassTestRule.html |  220 +--
 .../hadoop/hbase/class-use/HBaseTestingUtil.html   |  192 +-
 .../hbase/class-use/SingleProcessHBaseCluster.html |    8 +
 .../hadoop/hbase/master/TestMasterTransitions.html |    4 +-
 .../TestMasterUseIp.html}                          |  153 +-
 .../master/TestMergeTableRegionsWhileRSCrash.html  |    4 +-
 .../hbase/master/class-use/TestMasterUseIp.html    |  125 ++
 .../apache/hadoop/hbase/master/package-frame.html  |    1 +
 .../hadoop/hbase/master/package-summary.html       |   80 +-
 .../apache/hadoop/hbase/master/package-tree.html   |    1 +
 .../org/apache/hadoop/hbase/package-tree.html      |   18 +-
 .../hadoop/hbase/procedure2/package-tree.html      |    2 +-
 .../TestRegionServerScan.MyRSRpcServices.html      |    4 +-
 .../TestRegionServerUseIp.html}                    |  153 +-
 .../hbase/regionserver/TestRegionSplitPolicy.html  |    4 +-
 .../class-use/TestRegionServerUseIp.html           |  125 ++
 .../hadoop/hbase/regionserver/package-frame.html   |    1 +
 .../hadoop/hbase/regionserver/package-summary.html |  186 +-
 .../hadoop/hbase/regionserver/package-tree.html    |    7 +-
 .../org/apache/hadoop/hbase/test/package-tree.html |    4 +-
 .../util/TestRegionMover3.MockRackManager.html     |    4 +-
 ...SGroupEnable.html => TestRegionMoverUseIp.html} |  120 +-
 .../util/TestRegionMoverWithRSGroupEnable.html     |    4 +-
 .../hbase/util/class-use/TestRegionMoverUseIp.html |  125 ++
 .../apache/hadoop/hbase/util/package-frame.html    |    1 +
 .../apache/hadoop/hbase/util/package-summary.html  |   44 +-
 .../org/apache/hadoop/hbase/util/package-tree.html |    1 +
 .../org/apache/hadoop/hbase/wal/package-tree.html  |    4 +-
 testdevapidocs/overview-tree.html                  |    3 +
 .../hadoop/hbase/master/TestMasterUseIp.html       |  148 ++
 .../hbase/regionserver/TestRegionServerUseIp.html  |  148 ++
 .../hadoop/hbase/util/TestRegionMoverUseIp.html    |  211 +++
 120 files changed, 7828 insertions(+), 6461 deletions(-)

diff --git a/acid-semantics.html b/acid-semantics.html
index b0f4e213f35..f7f4acfc37e 100644
--- a/acid-semantics.html
+++ b/acid-semantics.html
@@ -464,7 +464,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/apache_hbase_reference_guide.pdf b/apache_hbase_reference_guide.pdf
index ecf75be0d49..c890990bf90 100644
--- a/apache_hbase_reference_guide.pdf
+++ b/apache_hbase_reference_guide.pdf
@@ -5,8 +5,8 @@
 /Author (Apache HBase Team)
 /Creator (Asciidoctor PDF 2.0.6, based on Prawn 2.4.0)
 /Producer (Apache HBase Team)
-/ModDate (D:20220921143051+00'00')
-/CreationDate (D:20220921144131+00'00')
+/ModDate (D:20220922143313+00'00')
+/CreationDate (D:20220922144400+00'00')
 >>
 endobj
 2 0 obj
diff --git a/apidocs/constant-values.html b/apidocs/constant-values.html
index 36b5749a399..9bad015c75e 100644
--- a/apidocs/constant-values.html
+++ b/apidocs/constant-values.html
@@ -1581,6 +1581,20 @@
 <td class="colLast"><code>"hbase.server.scanner.max.result.size"</code></td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><a name="org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT">
+<!--   -->
+</a><code>public&nbsp;static&nbsp;final&nbsp;boolean</code></td>
+<td><code><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_DEFAULT">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></code></td>
+<td class="colLast"><code>false</code></td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a name="org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_KEY">
+<!--   -->
+</a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td><code><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY">HBASE_SERVER_USEIP_ENABLED_KEY</a></code></td>
+<td class="colLast"><code>"hbase.server.useip.enabled"</code></td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK">
 <!--   -->
 </a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
diff --git a/apidocs/index-all.html b/apidocs/index-all.html
index e0f7ff95e18..31ccdcedbb7 100644
--- a/apidocs/index-all.html
+++ b/apidocs/index-all.html
@@ -9831,6 +9831,15 @@
 <dd>
 <div class="block">Parameter name for maximum number of bytes returned when calling a scanner's next method.</div>
 </dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_DEFAULT">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></span> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HConstants.html" title="class in org.apache.hadoop.hbase">HConstants</a></dt>
+<dd>
+<div class="block">Default value of <a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY"><code>HConstants.HBASE_SERVER_USEIP_ENABLED_KEY</code></a></div>
+</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY">HBASE_SERVER_USEIP_ENABLED_KEY</a></span> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HConstants.html" title="class in org.apache.hadoop.hbase">HConstants</a></dt>
+<dd>
+<div class="block">In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not
+ be able to resolve the hostname of the newly added node.</div>
+</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SPLIT_WAL_COORDINATED_BY_ZK">HBASE_SPLIT_WAL_COORDINATED_BY_ZK</a></span> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HConstants.html" title="class in org.apache.hadoop.hbase">HConstants</a></dt>
 <dd>
 <div class="block"><span class="deprecatedLabel">Deprecated.</span>
diff --git a/apidocs/org/apache/hadoop/hbase/HConstants.html b/apidocs/org/apache/hadoop/hbase/HConstants.html
index 0d3ca70615d..16bbd62e16a 100644
--- a/apidocs/org/apache/hadoop/hbase/HConstants.html
+++ b/apidocs/org/apache/hadoop/hbase/HConstants.html
@@ -1238,6 +1238,19 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><code>static boolean</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_DEFAULT">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></span></code>
+<div class="block">Default value of <a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY"><code>HBASE_SERVER_USEIP_ENABLED_KEY</code></a></div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY">HBASE_SERVER_USEIP_ENABLED_KEY</a></span></code>
+<div class="block">In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not
+ be able to resolve the hostname of the newly added node.</div>
+</td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SPLIT_WAL_COORDINATED_BY_ZK">HBASE_SPLIT_WAL_COORDINATED_BY_ZK</a></span></code>
 <div class="block"><span class="deprecatedLabel">Deprecated.</span>&nbsp;
@@ -7758,7 +7771,7 @@ public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop
 <a name="BATCH_ROWS_THRESHOLD_DEFAULT">
 <!--   -->
 </a>
-<ul class="blockListLast">
+<ul class="blockList">
 <li class="blockList">
 <h4>BATCH_ROWS_THRESHOLD_DEFAULT</h4>
 <pre>public static final&nbsp;int <a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1572">BATCH_ROWS_THRESHOLD_DEFAULT</a></pre>
@@ -7769,6 +7782,40 @@ public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop
 </dl>
 </li>
 </ul>
+<a name="HBASE_SERVER_USEIP_ENABLED_KEY">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>HBASE_SERVER_USEIP_ENABLED_KEY</h4>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1583">HBASE_SERVER_USEIP_ENABLED_KEY</a></pre>
+<div class="block">In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not
+ be able to resolve the hostname of the newly added node. If the network is interconnected, the
+ client can actually access the HBase cluster nodes through ip. However, since the HBase client
+ obtains the Master/RS address info from or the ZK or the meta table, so the Master/RS of the
+ HBase cluster needs to expose the service with ip instead of the hostname. Therefore, We can
+ use hostname by default, but at the same time, we can also provide a config to support whether
+ to use ip for Master/RS service. See HBASE-27304 for details.</div>
+<dl>
+<dt><span class="seeLabel">See Also:</span></dt>
+<dd><a href="../../../../constant-values.html#org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_KEY">Constant Field Values</a></dd>
+</dl>
+</li>
+</ul>
+<a name="HBASE_SERVER_USEIP_ENABLED_DEFAULT">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>HBASE_SERVER_USEIP_ENABLED_DEFAULT</h4>
+<pre>public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1588">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></pre>
+<div class="block">Default value of <a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY"><code>HBASE_SERVER_USEIP_ENABLED_KEY</code></a></div>
+<dl>
+<dt><span class="seeLabel">See Also:</span></dt>
+<dd><a href="../../../../constant-values.html#org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT">Constant Field Values</a></dd>
+</dl>
+</li>
+</ul>
 </li>
 </ul>
 </li>
diff --git a/apidocs/org/apache/hadoop/hbase/util/RegionMover.html b/apidocs/org/apache/hadoop/hbase/util/RegionMover.html
index 50797577cd7..7f70fd0f6e3 100644
--- a/apidocs/org/apache/hadoop/hbase/util/RegionMover.html
+++ b/apidocs/org/apache/hadoop/hbase/util/RegionMover.html
@@ -119,7 +119,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Public
-public class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.83">RegionMover</a>
+public class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.85">RegionMover</a>
 extends org.apache.hadoop.hbase.util.AbstractHBaseTool
 implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</a></pre>
 <div class="block">Tool for loading/unloading regions to/from given regionserver This tool can be run from Command
@@ -279,7 +279,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>MOVE_RETRIES_MAX_KEY</h4>
-<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.84">MOVE_RETRIES_MAX_KEY</a></pre>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.86">MOVE_RETRIES_MAX_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.MOVE_RETRIES_MAX_KEY">Constant Field Values</a></dd>
@@ -292,7 +292,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>MOVE_WAIT_MAX_KEY</h4>
-<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.85">MOVE_WAIT_MAX_KEY</a></pre>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.87">MOVE_WAIT_MAX_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.MOVE_WAIT_MAX_KEY">Constant Field Values</a></dd>
@@ -305,7 +305,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>SERVERSTART_WAIT_MAX_KEY</h4>
-<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.86">SERVERSTART_WAIT_MAX_KEY</a></pre>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.88">SERVERSTART_WAIT_MAX_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.SERVERSTART_WAIT_MAX_KEY">Constant Field Values</a></dd>
@@ -318,7 +318,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MOVE_RETRIES_MAX</h4>
-<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.87">DEFAULT_MOVE_RETRIES_MAX</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.89">DEFAULT_MOVE_RETRIES_MAX</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.DEFAULT_MOVE_RETRIES_MAX">Constant Field Values</a></dd>
@@ -331,7 +331,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MOVE_WAIT_MAX</h4>
-<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.88">DEFAULT_MOVE_WAIT_MAX</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.90">DEFAULT_MOVE_WAIT_MAX</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.DEFAULT_MOVE_WAIT_MAX">Constant Field Values</a></dd>
@@ -344,7 +344,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockListLast">
 <li class="blockList">
 <h4>DEFAULT_SERVERSTART_WAIT_MAX</h4>
-<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.89">DEFAULT_SERVERSTART_WAIT_MAX</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.91">DEFAULT_SERVERSTART_WAIT_MAX</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.DEFAULT_SERVERSTART_WAIT_MAX">Constant Field Values</a></dd>
@@ -365,7 +365,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>close</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.131">close</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.144">close</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html?is-external=true#close--" title="class or interface in java.io">close</a></code>&nbsp;in interface&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</a></code></dd>
@@ -380,7 +380,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>load</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.281">load</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.294">load</a>()
              throws <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                     <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                     <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -402,7 +402,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>unload</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.379">unload</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.392">unload</a>()
                throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                       <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                       <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -427,7 +427,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>unloadFromRack</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.393">unloadFromRack</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.406">unloadFromRack</a>()
                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -454,7 +454,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>addOptions</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.759">addOptions</a>()</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.772">addOptions</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code>org.apache.hadoop.hbase.util.AbstractHBaseTool</code></span></div>
 <div class="block">Override this to add command-line options using <code>AbstractHBaseTool.addOptWithArg(java.lang.String, java.lang.String)</code> and similar methods.</div>
 <dl>
@@ -469,7 +469,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>processOptions</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.782">processOptions</a>(org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine&nbsp;cmd)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.795">processOptions</a>(org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine&nbsp;cmd)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code>org.apache.hadoop.hbase.util.AbstractHBaseTool</code></span></div>
 <div class="block">This method is called to process the options after they have been parsed.</div>
 <dl>
@@ -484,7 +484,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>doWork</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.807">doWork</a>()
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.820">doWork</a>()
               throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code>org.apache.hadoop.hbase.util.AbstractHBaseTool</code></span></div>
 <div class="block">The "main function" of the tool</div>
@@ -502,7 +502,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockListLast">
 <li class="blockList">
 <h4>main</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.824">main</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]&nbsp;args)</pre>
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.837">main</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]&nbsp;args)</pre>
 </li>
 </ul>
 </li>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/HConstants.html b/apidocs/src-html/org/apache/hadoop/hbase/HConstants.html
index 5a0d8c2b2ea..9112019978f 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/HConstants.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/HConstants.html
@@ -1579,10 +1579,26 @@
 <span class="sourceLineNo">1571</span>   */<a name="line.1571"></a>
 <span class="sourceLineNo">1572</span>  public static final int BATCH_ROWS_THRESHOLD_DEFAULT = 5000;<a name="line.1572"></a>
 <span class="sourceLineNo">1573</span><a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>  private HConstants() {<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>    // Can't be instantiated with this ctor.<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>  }<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>}<a name="line.1577"></a>
+<span class="sourceLineNo">1574</span>  /**<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>   * In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>   * be able to resolve the hostname of the newly added node. If the network is interconnected, the<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>   * client can actually access the HBase cluster nodes through ip. However, since the HBase client<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>   * obtains the Master/RS address info from or the ZK or the meta table, so the Master/RS of the<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>   * HBase cluster needs to expose the service with ip instead of the hostname. Therefore, We can<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>   * use hostname by default, but at the same time, we can also provide a config to support whether<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span>   * to use ip for Master/RS service. See HBASE-27304 for details.<a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>   */<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>  public final static String HBASE_SERVER_USEIP_ENABLED_KEY = "hbase.server.useip.enabled";<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span><a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>  /**<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>   * Default value of {@link #HBASE_SERVER_USEIP_ENABLED_KEY}<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span>   */<a name="line.1587"></a>
+<span class="sourceLineNo">1588</span>  public final static boolean HBASE_SERVER_USEIP_ENABLED_DEFAULT = false;<a name="line.1588"></a>
+<span class="sourceLineNo">1589</span><a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>  private HConstants() {<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>    // Can't be instantiated with this ctor.<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>  }<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>}<a name="line.1593"></a>
 
 
 
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/util/RegionMover.html b/apidocs/src-html/org/apache/hadoop/hbase/util/RegionMover.html
index 693d9f12912..47ff71a3504 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/util/RegionMover.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/util/RegionMover.html
@@ -34,807 +34,820 @@
 <span class="sourceLineNo">026</span>import java.io.FileInputStream;<a name="line.26"></a>
 <span class="sourceLineNo">027</span>import java.io.FileOutputStream;<a name="line.27"></a>
 <span class="sourceLineNo">028</span>import java.io.IOException;<a name="line.28"></a>
-<span class="sourceLineNo">029</span>import java.nio.file.Files;<a name="line.29"></a>
-<span class="sourceLineNo">030</span>import java.nio.file.Paths;<a name="line.30"></a>
-<span class="sourceLineNo">031</span>import java.util.ArrayList;<a name="line.31"></a>
-<span class="sourceLineNo">032</span>import java.util.Collection;<a name="line.32"></a>
-<span class="sourceLineNo">033</span>import java.util.Collections;<a name="line.33"></a>
-<span class="sourceLineNo">034</span>import java.util.EnumSet;<a name="line.34"></a>
-<span class="sourceLineNo">035</span>import java.util.HashSet;<a name="line.35"></a>
-<span class="sourceLineNo">036</span>import java.util.Iterator;<a name="line.36"></a>
-<span class="sourceLineNo">037</span>import java.util.List;<a name="line.37"></a>
-<span class="sourceLineNo">038</span>import java.util.Locale;<a name="line.38"></a>
-<span class="sourceLineNo">039</span>import java.util.Optional;<a name="line.39"></a>
-<span class="sourceLineNo">040</span>import java.util.Set;<a name="line.40"></a>
-<span class="sourceLineNo">041</span>import java.util.concurrent.Callable;<a name="line.41"></a>
-<span class="sourceLineNo">042</span>import java.util.concurrent.CancellationException;<a name="line.42"></a>
-<span class="sourceLineNo">043</span>import java.util.concurrent.ExecutionException;<a name="line.43"></a>
-<span class="sourceLineNo">044</span>import java.util.concurrent.ExecutorService;<a name="line.44"></a>
-<span class="sourceLineNo">045</span>import java.util.concurrent.Executors;<a name="line.45"></a>
-<span class="sourceLineNo">046</span>import java.util.concurrent.Future;<a name="line.46"></a>
-<span class="sourceLineNo">047</span>import java.util.concurrent.TimeUnit;<a name="line.47"></a>
-<span class="sourceLineNo">048</span>import java.util.concurrent.TimeoutException;<a name="line.48"></a>
-<span class="sourceLineNo">049</span>import java.util.function.Predicate;<a name="line.49"></a>
-<span class="sourceLineNo">050</span>import org.apache.commons.io.IOUtils;<a name="line.50"></a>
-<span class="sourceLineNo">051</span>import org.apache.hadoop.conf.Configuration;<a name="line.51"></a>
-<span class="sourceLineNo">052</span>import org.apache.hadoop.hbase.ClusterMetrics.Option;<a name="line.52"></a>
-<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.HBaseConfiguration;<a name="line.53"></a>
-<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.HConstants;<a name="line.54"></a>
-<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.ServerName;<a name="line.55"></a>
-<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.UnknownRegionException;<a name="line.56"></a>
-<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.client.Admin;<a name="line.57"></a>
-<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.client.Connection;<a name="line.58"></a>
-<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.client.ConnectionFactory;<a name="line.59"></a>
-<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.client.DoNotRetryRegionException;<a name="line.60"></a>
-<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.61"></a>
-<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.62"></a>
-<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.master.assignment.AssignmentManager;<a name="line.63"></a>
-<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.net.Address;<a name="line.64"></a>
-<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.rsgroup.RSGroupInfo;<a name="line.65"></a>
-<span class="sourceLineNo">066</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.66"></a>
-<span class="sourceLineNo">067</span>import org.slf4j.Logger;<a name="line.67"></a>
-<span class="sourceLineNo">068</span>import org.slf4j.LoggerFactory;<a name="line.68"></a>
-<span class="sourceLineNo">069</span><a name="line.69"></a>
-<span class="sourceLineNo">070</span>import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;<a name="line.70"></a>
-<span class="sourceLineNo">071</span>import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils;<a name="line.71"></a>
-<span class="sourceLineNo">072</span><a name="line.72"></a>
-<span class="sourceLineNo">073</span>/**<a name="line.73"></a>
-<span class="sourceLineNo">074</span> * Tool for loading/unloading regions to/from given regionserver This tool can be run from Command<a name="line.74"></a>
-<span class="sourceLineNo">075</span> * line directly as a utility. Supports Ack/No Ack mode for loading/unloading operations.Ack mode<a name="line.75"></a>
-<span class="sourceLineNo">076</span> * acknowledges if regions are online after movement while noAck mode is best effort mode that<a name="line.76"></a>
-<span class="sourceLineNo">077</span> * improves performance but will still move on if region is stuck/not moved. Motivation behind noAck<a name="line.77"></a>
-<span class="sourceLineNo">078</span> * mode being RS shutdown where even if a Region is stuck, upon shutdown master will move it<a name="line.78"></a>
-<span class="sourceLineNo">079</span> * anyways. This can also be used by constructiong an Object using the builder and then calling<a name="line.79"></a>
-<span class="sourceLineNo">080</span> * {@link #load()} or {@link #unload()} methods for the desired operations.<a name="line.80"></a>
-<span class="sourceLineNo">081</span> */<a name="line.81"></a>
-<span class="sourceLineNo">082</span>@InterfaceAudience.Public<a name="line.82"></a>
-<span class="sourceLineNo">083</span>public class RegionMover extends AbstractHBaseTool implements Closeable {<a name="line.83"></a>
-<span class="sourceLineNo">084</span>  public static final String MOVE_RETRIES_MAX_KEY = "hbase.move.retries.max";<a name="line.84"></a>
-<span class="sourceLineNo">085</span>  public static final String MOVE_WAIT_MAX_KEY = "hbase.move.wait.max";<a name="line.85"></a>
-<span class="sourceLineNo">086</span>  public static final String SERVERSTART_WAIT_MAX_KEY = "hbase.serverstart.wait.max";<a name="line.86"></a>
-<span class="sourceLineNo">087</span>  public static final int DEFAULT_MOVE_RETRIES_MAX = 5;<a name="line.87"></a>
-<span class="sourceLineNo">088</span>  public static final int DEFAULT_MOVE_WAIT_MAX = 60;<a name="line.88"></a>
-<span class="sourceLineNo">089</span>  public static final int DEFAULT_SERVERSTART_WAIT_MAX = 180;<a name="line.89"></a>
-<span class="sourceLineNo">090</span><a name="line.90"></a>
-<span class="sourceLineNo">091</span>  private static final Logger LOG = LoggerFactory.getLogger(RegionMover.class);<a name="line.91"></a>
+<span class="sourceLineNo">029</span>import java.net.InetAddress;<a name="line.29"></a>
+<span class="sourceLineNo">030</span>import java.nio.file.Files;<a name="line.30"></a>
+<span class="sourceLineNo">031</span>import java.nio.file.Paths;<a name="line.31"></a>
+<span class="sourceLineNo">032</span>import java.util.ArrayList;<a name="line.32"></a>
+<span class="sourceLineNo">033</span>import java.util.Collection;<a name="line.33"></a>
+<span class="sourceLineNo">034</span>import java.util.Collections;<a name="line.34"></a>
+<span class="sourceLineNo">035</span>import java.util.EnumSet;<a name="line.35"></a>
+<span class="sourceLineNo">036</span>import java.util.HashSet;<a name="line.36"></a>
+<span class="sourceLineNo">037</span>import java.util.Iterator;<a name="line.37"></a>
+<span class="sourceLineNo">038</span>import java.util.List;<a name="line.38"></a>
+<span class="sourceLineNo">039</span>import java.util.Locale;<a name="line.39"></a>
+<span class="sourceLineNo">040</span>import java.util.Optional;<a name="line.40"></a>
+<span class="sourceLineNo">041</span>import java.util.Set;<a name="line.41"></a>
+<span class="sourceLineNo">042</span>import java.util.concurrent.Callable;<a name="line.42"></a>
+<span class="sourceLineNo">043</span>import java.util.concurrent.CancellationException;<a name="line.43"></a>
+<span class="sourceLineNo">044</span>import java.util.concurrent.ExecutionException;<a name="line.44"></a>
+<span class="sourceLineNo">045</span>import java.util.concurrent.ExecutorService;<a name="line.45"></a>
+<span class="sourceLineNo">046</span>import java.util.concurrent.Executors;<a name="line.46"></a>
+<span class="sourceLineNo">047</span>import java.util.concurrent.Future;<a name="line.47"></a>
+<span class="sourceLineNo">048</span>import java.util.concurrent.TimeUnit;<a name="line.48"></a>
+<span class="sourceLineNo">049</span>import java.util.concurrent.TimeoutException;<a name="line.49"></a>
+<span class="sourceLineNo">050</span>import java.util.function.Predicate;<a name="line.50"></a>
+<span class="sourceLineNo">051</span>import org.apache.commons.io.IOUtils;<a name="line.51"></a>
+<span class="sourceLineNo">052</span>import org.apache.hadoop.conf.Configuration;<a name="line.52"></a>
+<span class="sourceLineNo">053</span>import org.apache.hadoop.hbase.ClusterMetrics.Option;<a name="line.53"></a>
+<span class="sourceLineNo">054</span>import org.apache.hadoop.hbase.HBaseConfiguration;<a name="line.54"></a>
+<span class="sourceLineNo">055</span>import org.apache.hadoop.hbase.HConstants;<a name="line.55"></a>
+<span class="sourceLineNo">056</span>import org.apache.hadoop.hbase.ServerName;<a name="line.56"></a>
+<span class="sourceLineNo">057</span>import org.apache.hadoop.hbase.UnknownRegionException;<a name="line.57"></a>
+<span class="sourceLineNo">058</span>import org.apache.hadoop.hbase.client.Admin;<a name="line.58"></a>
+<span class="sourceLineNo">059</span>import org.apache.hadoop.hbase.client.Connection;<a name="line.59"></a>
+<span class="sourceLineNo">060</span>import org.apache.hadoop.hbase.client.ConnectionFactory;<a name="line.60"></a>
+<span class="sourceLineNo">061</span>import org.apache.hadoop.hbase.client.DoNotRetryRegionException;<a name="line.61"></a>
+<span class="sourceLineNo">062</span>import org.apache.hadoop.hbase.client.RegionInfo;<a name="line.62"></a>
+<span class="sourceLineNo">063</span>import org.apache.hadoop.hbase.master.RackManager;<a name="line.63"></a>
+<span class="sourceLineNo">064</span>import org.apache.hadoop.hbase.master.assignment.AssignmentManager;<a name="line.64"></a>
+<span class="sourceLineNo">065</span>import org.apache.hadoop.hbase.net.Address;<a name="line.65"></a>
+<span class="sourceLineNo">066</span>import org.apache.hadoop.hbase.rsgroup.RSGroupInfo;<a name="line.66"></a>
+<span class="sourceLineNo">067</span>import org.apache.yetus.audience.InterfaceAudience;<a name="line.67"></a>
+<span class="sourceLineNo">068</span>import org.slf4j.Logger;<a name="line.68"></a>
+<span class="sourceLineNo">069</span>import org.slf4j.LoggerFactory;<a name="line.69"></a>
+<span class="sourceLineNo">070</span><a name="line.70"></a>
+<span class="sourceLineNo">071</span>import org.apache.hbase.thirdparty.com.google.common.net.InetAddresses;<a name="line.71"></a>
+<span class="sourceLineNo">072</span>import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;<a name="line.72"></a>
+<span class="sourceLineNo">073</span>import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils;<a name="line.73"></a>
+<span class="sourceLineNo">074</span><a name="line.74"></a>
+<span class="sourceLineNo">075</span>/**<a name="line.75"></a>
+<span class="sourceLineNo">076</span> * Tool for loading/unloading regions to/from given regionserver This tool can be run from Command<a name="line.76"></a>
+<span class="sourceLineNo">077</span> * line directly as a utility. Supports Ack/No Ack mode for loading/unloading operations.Ack mode<a name="line.77"></a>
+<span class="sourceLineNo">078</span> * acknowledges if regions are online after movement while noAck mode is best effort mode that<a name="line.78"></a>
+<span class="sourceLineNo">079</span> * improves performance but will still move on if region is stuck/not moved. Motivation behind noAck<a name="line.79"></a>
+<span class="sourceLineNo">080</span> * mode being RS shutdown where even if a Region is stuck, upon shutdown master will move it<a name="line.80"></a>
+<span class="sourceLineNo">081</span> * anyways. This can also be used by constructiong an Object using the builder and then calling<a name="line.81"></a>
+<span class="sourceLineNo">082</span> * {@link #load()} or {@link #unload()} methods for the desired operations.<a name="line.82"></a>
+<span class="sourceLineNo">083</span> */<a name="line.83"></a>
+<span class="sourceLineNo">084</span>@InterfaceAudience.Public<a name="line.84"></a>
+<span class="sourceLineNo">085</span>public class RegionMover extends AbstractHBaseTool implements Closeable {<a name="line.85"></a>
+<span class="sourceLineNo">086</span>  public static final String MOVE_RETRIES_MAX_KEY = "hbase.move.retries.max";<a name="line.86"></a>
+<span class="sourceLineNo">087</span>  public static final String MOVE_WAIT_MAX_KEY = "hbase.move.wait.max";<a name="line.87"></a>
+<span class="sourceLineNo">088</span>  public static final String SERVERSTART_WAIT_MAX_KEY = "hbase.serverstart.wait.max";<a name="line.88"></a>
+<span class="sourceLineNo">089</span>  public static final int DEFAULT_MOVE_RETRIES_MAX = 5;<a name="line.89"></a>
+<span class="sourceLineNo">090</span>  public static final int DEFAULT_MOVE_WAIT_MAX = 60;<a name="line.90"></a>
+<span class="sourceLineNo">091</span>  public static final int DEFAULT_SERVERSTART_WAIT_MAX = 180;<a name="line.91"></a>
 <span class="sourceLineNo">092</span><a name="line.92"></a>
-<span class="sourceLineNo">093</span>  private RegionMoverBuilder rmbuilder;<a name="line.93"></a>
-<span class="sourceLineNo">094</span>  private boolean ack = true;<a name="line.94"></a>
-<span class="sourceLineNo">095</span>  private int maxthreads = 1;<a name="line.95"></a>
-<span class="sourceLineNo">096</span>  private int timeout;<a name="line.96"></a>
-<span class="sourceLineNo">097</span>  private String loadUnload;<a name="line.97"></a>
-<span class="sourceLineNo">098</span>  private String hostname;<a name="line.98"></a>
-<span class="sourceLineNo">099</span>  private String filename;<a name="line.99"></a>
-<span class="sourceLineNo">100</span>  private String excludeFile;<a name="line.100"></a>
-<span class="sourceLineNo">101</span>  private String designatedFile;<a name="line.101"></a>
-<span class="sourceLineNo">102</span>  private int port;<a name="line.102"></a>
-<span class="sourceLineNo">103</span>  private Connection conn;<a name="line.103"></a>
-<span class="sourceLineNo">104</span>  private Admin admin;<a name="line.104"></a>
-<span class="sourceLineNo">105</span>  private RackManager rackManager;<a name="line.105"></a>
-<span class="sourceLineNo">106</span><a name="line.106"></a>
-<span class="sourceLineNo">107</span>  private RegionMover(RegionMoverBuilder builder) throws IOException {<a name="line.107"></a>
-<span class="sourceLineNo">108</span>    this.hostname = builder.hostname;<a name="line.108"></a>
-<span class="sourceLineNo">109</span>    this.filename = builder.filename;<a name="line.109"></a>
-<span class="sourceLineNo">110</span>    this.excludeFile = builder.excludeFile;<a name="line.110"></a>
-<span class="sourceLineNo">111</span>    this.designatedFile = builder.designatedFile;<a name="line.111"></a>
-<span class="sourceLineNo">112</span>    this.maxthreads = builder.maxthreads;<a name="line.112"></a>
-<span class="sourceLineNo">113</span>    this.ack = builder.ack;<a name="line.113"></a>
-<span class="sourceLineNo">114</span>    this.port = builder.port;<a name="line.114"></a>
-<span class="sourceLineNo">115</span>    this.timeout = builder.timeout;<a name="line.115"></a>
-<span class="sourceLineNo">116</span>    setConf(builder.conf);<a name="line.116"></a>
-<span class="sourceLineNo">117</span>    this.conn = ConnectionFactory.createConnection(conf);<a name="line.117"></a>
-<span class="sourceLineNo">118</span>    this.admin = conn.getAdmin();<a name="line.118"></a>
-<span class="sourceLineNo">119</span>    // Only while running unit tests, builder.rackManager will not be null for the convenience of<a name="line.119"></a>
-<span class="sourceLineNo">120</span>    // providing custom rackManager. Otherwise for regular workflow/user triggered action,<a name="line.120"></a>
-<span class="sourceLineNo">121</span>    // builder.rackManager is supposed to be null. Hence, setter of builder.rackManager is<a name="line.121"></a>
-<span class="sourceLineNo">122</span>    // provided as @InterfaceAudience.Private and it is commented that this is just<a name="line.122"></a>
-<span class="sourceLineNo">123</span>    // to be used by unit test.<a name="line.123"></a>
-<span class="sourceLineNo">124</span>    rackManager = builder.rackManager == null ? new RackManager(conf) : builder.rackManager;<a name="line.124"></a>
-<span class="sourceLineNo">125</span>  }<a name="line.125"></a>
-<span class="sourceLineNo">126</span><a name="line.126"></a>
-<span class="sourceLineNo">127</span>  private RegionMover() {<a name="line.127"></a>
-<span class="sourceLineNo">128</span>  }<a name="line.128"></a>
-<span class="sourceLineNo">129</span><a name="line.129"></a>
-<span class="sourceLineNo">130</span>  @Override<a name="line.130"></a>
-<span class="sourceLineNo">131</span>  public void close() {<a name="line.131"></a>
-<span class="sourceLineNo">132</span>    IOUtils.closeQuietly(this.admin, e -&gt; LOG.warn("failed to close admin", e));<a name="line.132"></a>
-<span class="sourceLineNo">133</span>    IOUtils.closeQuietly(this.conn, e -&gt; LOG.warn("failed to close conn", e));<a name="line.133"></a>
-<span class="sourceLineNo">134</span>  }<a name="line.134"></a>
-<span class="sourceLineNo">135</span><a name="line.135"></a>
-<span class="sourceLineNo">136</span>  /**<a name="line.136"></a>
-<span class="sourceLineNo">137</span>   * Builder for Region mover. Use the {@link #build()} method to create RegionMover object. Has<a name="line.137"></a>
-<span class="sourceLineNo">138</span>   * {@link #filename(String)}, {@link #excludeFile(String)}, {@link #maxthreads(int)},<a name="line.138"></a>
-<span class="sourceLineNo">139</span>   * {@link #ack(boolean)}, {@link #timeout(int)}, {@link #designatedFile(String)} methods to set<a name="line.139"></a>
-<span class="sourceLineNo">140</span>   * the corresponding options.<a name="line.140"></a>
-<span class="sourceLineNo">141</span>   */<a name="line.141"></a>
-<span class="sourceLineNo">142</span>  public static class RegionMoverBuilder {<a name="line.142"></a>
-<span class="sourceLineNo">143</span>    private boolean ack = true;<a name="line.143"></a>
-<span class="sourceLineNo">144</span>    private int maxthreads = 1;<a name="line.144"></a>
-<span class="sourceLineNo">145</span>    private int timeout = Integer.MAX_VALUE;<a name="line.145"></a>
-<span class="sourceLineNo">146</span>    private String hostname;<a name="line.146"></a>
-<span class="sourceLineNo">147</span>    private String filename;<a name="line.147"></a>
-<span class="sourceLineNo">148</span>    private String excludeFile = null;<a name="line.148"></a>
-<span class="sourceLineNo">149</span>    private String designatedFile = null;<a name="line.149"></a>
-<span class="sourceLineNo">150</span>    private String defaultDir = System.getProperty("java.io.tmpdir");<a name="line.150"></a>
-<span class="sourceLineNo">151</span>    @InterfaceAudience.Private<a name="line.151"></a>
-<span class="sourceLineNo">152</span>    final int port;<a name="line.152"></a>
-<span class="sourceLineNo">153</span>    private final Configuration conf;<a name="line.153"></a>
-<span class="sourceLineNo">154</span>    private RackManager rackManager;<a name="line.154"></a>
-<span class="sourceLineNo">155</span><a name="line.155"></a>
-<span class="sourceLineNo">156</span>    public RegionMoverBuilder(String hostname) {<a name="line.156"></a>
-<span class="sourceLineNo">157</span>      this(hostname, createConf());<a name="line.157"></a>
-<span class="sourceLineNo">158</span>    }<a name="line.158"></a>
-<span class="sourceLineNo">159</span><a name="line.159"></a>
-<span class="sourceLineNo">160</span>    /**<a name="line.160"></a>
-<span class="sourceLineNo">161</span>     * Creates a new configuration and sets region mover specific overrides<a name="line.161"></a>
-<span class="sourceLineNo">162</span>     */<a name="line.162"></a>
-<span class="sourceLineNo">163</span>    private static Configuration createConf() {<a name="line.163"></a>
-<span class="sourceLineNo">164</span>      Configuration conf = HBaseConfiguration.create();<a name="line.164"></a>
-<span class="sourceLineNo">165</span>      conf.setInt("hbase.client.prefetch.limit", 1);<a name="line.165"></a>
-<span class="sourceLineNo">166</span>      conf.setInt("hbase.client.pause", 500);<a name="line.166"></a>
-<span class="sourceLineNo">167</span>      conf.setInt("hbase.client.retries.number", 100);<a name="line.167"></a>
-<span class="sourceLineNo">168</span>      return conf;<a name="line.168"></a>
-<span class="sourceLineNo">169</span>    }<a name="line.169"></a>
-<span class="sourceLineNo">170</span><a name="line.170"></a>
-<span class="sourceLineNo">171</span>    /**<a name="line.171"></a>
-<span class="sourceLineNo">172</span>     * @param hostname Hostname to unload regions from or load regions to. Can be either hostname or<a name="line.172"></a>
-<span class="sourceLineNo">173</span>     *                 hostname:port.<a name="line.173"></a>
-<span class="sourceLineNo">174</span>     * @param conf     Configuration object<a name="line.174"></a>
+<span class="sourceLineNo">093</span>  private static final Logger LOG = LoggerFactory.getLogger(RegionMover.class);<a name="line.93"></a>
+<span class="sourceLineNo">094</span><a name="line.94"></a>
+<span class="sourceLineNo">095</span>  private RegionMoverBuilder rmbuilder;<a name="line.95"></a>
+<span class="sourceLineNo">096</span>  private boolean ack = true;<a name="line.96"></a>
+<span class="sourceLineNo">097</span>  private int maxthreads = 1;<a name="line.97"></a>
+<span class="sourceLineNo">098</span>  private int timeout;<a name="line.98"></a>
+<span class="sourceLineNo">099</span>  private String loadUnload;<a name="line.99"></a>
+<span class="sourceLineNo">100</span>  private String hostname;<a name="line.100"></a>
+<span class="sourceLineNo">101</span>  private String filename;<a name="line.101"></a>
+<span class="sourceLineNo">102</span>  private String excludeFile;<a name="line.102"></a>
+<span class="sourceLineNo">103</span>  private String designatedFile;<a name="line.103"></a>
+<span class="sourceLineNo">104</span>  private int port;<a name="line.104"></a>
+<span class="sourceLineNo">105</span>  private Connection conn;<a name="line.105"></a>
+<span class="sourceLineNo">106</span>  private Admin admin;<a name="line.106"></a>
+<span class="sourceLineNo">107</span>  private RackManager rackManager;<a name="line.107"></a>
+<span class="sourceLineNo">108</span><a name="line.108"></a>
+<span class="sourceLineNo">109</span>  private RegionMover(RegionMoverBuilder builder) throws IOException {<a name="line.109"></a>
+<span class="sourceLineNo">110</span>    this.hostname = builder.hostname;<a name="line.110"></a>
+<span class="sourceLineNo">111</span>    this.filename = builder.filename;<a name="line.111"></a>
+<span class="sourceLineNo">112</span>    this.excludeFile = builder.excludeFile;<a name="line.112"></a>
+<span class="sourceLineNo">113</span>    this.designatedFile = builder.designatedFile;<a name="line.113"></a>
+<span class="sourceLineNo">114</span>    this.maxthreads = builder.maxthreads;<a name="line.114"></a>
+<span class="sourceLineNo">115</span>    this.ack = builder.ack;<a name="line.115"></a>
+<span class="sourceLineNo">116</span>    this.port = builder.port;<a name="line.116"></a>
+<span class="sourceLineNo">117</span>    this.timeout = builder.timeout;<a name="line.117"></a>
+<span class="sourceLineNo">118</span>    setConf(builder.conf);<a name="line.118"></a>
+<span class="sourceLineNo">119</span>    this.conn = ConnectionFactory.createConnection(conf);<a name="line.119"></a>
+<span class="sourceLineNo">120</span>    this.admin = conn.getAdmin();<a name="line.120"></a>
+<span class="sourceLineNo">121</span><a name="line.121"></a>
+<span class="sourceLineNo">122</span>    // if the hostname of master is ip, it indicates that the master/RS has enabled use-ip, we need<a name="line.122"></a>
+<span class="sourceLineNo">123</span>    // to resolve the current hostname to ip to ensure that the RegionMover logic can be executed<a name="line.123"></a>
+<span class="sourceLineNo">124</span>    // normally, see HBASE-27304 for details.<a name="line.124"></a>
+<span class="sourceLineNo">125</span>    ServerName master = admin.getClusterMetrics(EnumSet.of(Option.MASTER)).getMasterName();<a name="line.125"></a>
+<span class="sourceLineNo">126</span>    if (InetAddresses.isInetAddress(master.getHostname())) {<a name="line.126"></a>
+<span class="sourceLineNo">127</span>      if (!InetAddresses.isInetAddress(this.hostname)) {<a name="line.127"></a>
+<span class="sourceLineNo">128</span>        this.hostname = InetAddress.getByName(this.hostname).getHostAddress();<a name="line.128"></a>
+<span class="sourceLineNo">129</span>      }<a name="line.129"></a>
+<span class="sourceLineNo">130</span>    }<a name="line.130"></a>
+<span class="sourceLineNo">131</span><a name="line.131"></a>
+<span class="sourceLineNo">132</span>    // Only while running unit tests, builder.rackManager will not be null for the convenience of<a name="line.132"></a>
+<span class="sourceLineNo">133</span>    // providing custom rackManager. Otherwise for regular workflow/user triggered action,<a name="line.133"></a>
+<span class="sourceLineNo">134</span>    // builder.rackManager is supposed to be null. Hence, setter of builder.rackManager is<a name="line.134"></a>
+<span class="sourceLineNo">135</span>    // provided as @InterfaceAudience.Private and it is commented that this is just<a name="line.135"></a>
+<span class="sourceLineNo">136</span>    // to be used by unit test.<a name="line.136"></a>
+<span class="sourceLineNo">137</span>    rackManager = builder.rackManager == null ? new RackManager(conf) : builder.rackManager;<a name="line.137"></a>
+<span class="sourceLineNo">138</span>  }<a name="line.138"></a>
+<span class="sourceLineNo">139</span><a name="line.139"></a>
+<span class="sourceLineNo">140</span>  private RegionMover() {<a name="line.140"></a>
+<span class="sourceLineNo">141</span>  }<a name="line.141"></a>
+<span class="sourceLineNo">142</span><a name="line.142"></a>
+<span class="sourceLineNo">143</span>  @Override<a name="line.143"></a>
+<span class="sourceLineNo">144</span>  public void close() {<a name="line.144"></a>
+<span class="sourceLineNo">145</span>    IOUtils.closeQuietly(this.admin, e -&gt; LOG.warn("failed to close admin", e));<a name="line.145"></a>
+<span class="sourceLineNo">146</span>    IOUtils.closeQuietly(this.conn, e -&gt; LOG.warn("failed to close conn", e));<a name="line.146"></a>
+<span class="sourceLineNo">147</span>  }<a name="line.147"></a>
+<span class="sourceLineNo">148</span><a name="line.148"></a>
+<span class="sourceLineNo">149</span>  /**<a name="line.149"></a>
+<span class="sourceLineNo">150</span>   * Builder for Region mover. Use the {@link #build()} method to create RegionMover object. Has<a name="line.150"></a>
+<span class="sourceLineNo">151</span>   * {@link #filename(String)}, {@link #excludeFile(String)}, {@link #maxthreads(int)},<a name="line.151"></a>
+<span class="sourceLineNo">152</span>   * {@link #ack(boolean)}, {@link #timeout(int)}, {@link #designatedFile(String)} methods to set<a name="line.152"></a>
+<span class="sourceLineNo">153</span>   * the corresponding options.<a name="line.153"></a>
+<span class="sourceLineNo">154</span>   */<a name="line.154"></a>
+<span class="sourceLineNo">155</span>  public static class RegionMoverBuilder {<a name="line.155"></a>
+<span class="sourceLineNo">156</span>    private boolean ack = true;<a name="line.156"></a>
+<span class="sourceLineNo">157</span>    private int maxthreads = 1;<a name="line.157"></a>
+<span class="sourceLineNo">158</span>    private int timeout = Integer.MAX_VALUE;<a name="line.158"></a>
+<span class="sourceLineNo">159</span>    private String hostname;<a name="line.159"></a>
+<span class="sourceLineNo">160</span>    private String filename;<a name="line.160"></a>
+<span class="sourceLineNo">161</span>    private String excludeFile = null;<a name="line.161"></a>
+<span class="sourceLineNo">162</span>    private String designatedFile = null;<a name="line.162"></a>
+<span class="sourceLineNo">163</span>    private String defaultDir = System.getProperty("java.io.tmpdir");<a name="line.163"></a>
+<span class="sourceLineNo">164</span>    @InterfaceAudience.Private<a name="line.164"></a>
+<span class="sourceLineNo">165</span>    final int port;<a name="line.165"></a>
+<span class="sourceLineNo">166</span>    private final Configuration conf;<a name="line.166"></a>
+<span class="sourceLineNo">167</span>    private RackManager rackManager;<a name="line.167"></a>
+<span class="sourceLineNo">168</span><a name="line.168"></a>
+<span class="sourceLineNo">169</span>    public RegionMoverBuilder(String hostname) {<a name="line.169"></a>
+<span class="sourceLineNo">170</span>      this(hostname, createConf());<a name="line.170"></a>
+<span class="sourceLineNo">171</span>    }<a name="line.171"></a>
+<span class="sourceLineNo">172</span><a name="line.172"></a>
+<span class="sourceLineNo">173</span>    /**<a name="line.173"></a>
+<span class="sourceLineNo">174</span>     * Creates a new configuration and sets region mover specific overrides<a name="line.174"></a>
 <span class="sourceLineNo">175</span>     */<a name="line.175"></a>
-<span class="sourceLineNo">176</span>    public RegionMoverBuilder(String hostname, Configuration conf) {<a name="line.176"></a>
-<span class="sourceLineNo">177</span>      String[] splitHostname = hostname.toLowerCase().split(":");<a name="line.177"></a>
-<span class="sourceLineNo">178</span>      this.hostname = splitHostname[0];<a name="line.178"></a>
-<span class="sourceLineNo">179</span>      if (splitHostname.length == 2) {<a name="line.179"></a>
-<span class="sourceLineNo">180</span>        this.port = Integer.parseInt(splitHostname[1]);<a name="line.180"></a>
-<span class="sourceLineNo">181</span>      } else {<a name="line.181"></a>
-<span class="sourceLineNo">182</span>        this.port = conf.getInt(HConstants.REGIONSERVER_PORT, HConstants.DEFAULT_REGIONSERVER_PORT);<a name="line.182"></a>
-<span class="sourceLineNo">183</span>      }<a name="line.183"></a>
-<span class="sourceLineNo">184</span>      this.filename = defaultDir + File.separator + System.getProperty("user.name") + this.hostname<a name="line.184"></a>
-<span class="sourceLineNo">185</span>        + ":" + Integer.toString(this.port);<a name="line.185"></a>
-<span class="sourceLineNo">186</span>      this.conf = conf;<a name="line.186"></a>
-<span class="sourceLineNo">187</span>    }<a name="line.187"></a>
-<span class="sourceLineNo">188</span><a name="line.188"></a>
-<span class="sourceLineNo">189</span>    /**<a name="line.189"></a>
-<span class="sourceLineNo">190</span>     * Path of file where regions will be written to during unloading/read from during loading n<a name="line.190"></a>
-<span class="sourceLineNo">191</span>     * * @return RegionMoverBuilder object<a name="line.191"></a>
-<span class="sourceLineNo">192</span>     */<a name="line.192"></a>
-<span class="sourceLineNo">193</span>    public RegionMoverBuilder filename(String filename) {<a name="line.193"></a>
-<span class="sourceLineNo">194</span>      this.filename = filename;<a name="line.194"></a>
-<span class="sourceLineNo">195</span>      return this;<a name="line.195"></a>
-<span class="sourceLineNo">196</span>    }<a name="line.196"></a>
-<span class="sourceLineNo">197</span><a name="line.197"></a>
-<span class="sourceLineNo">198</span>    /**<a name="line.198"></a>
-<span class="sourceLineNo">199</span>     * Set the max number of threads that will be used to move regions<a name="line.199"></a>
-<span class="sourceLineNo">200</span>     */<a name="line.200"></a>
-<span class="sourceLineNo">201</span>    public RegionMoverBuilder maxthreads(int threads) {<a name="line.201"></a>
-<span class="sourceLineNo">202</span>      this.maxthreads = threads;<a name="line.202"></a>
-<span class="sourceLineNo">203</span>      return this;<a name="line.203"></a>
-<span class="sourceLineNo">204</span>    }<a name="line.204"></a>
-<span class="sourceLineNo">205</span><a name="line.205"></a>
-<span class="sourceLineNo">206</span>    /**<a name="line.206"></a>
-<span class="sourceLineNo">207</span>     * Path of file containing hostnames to be excluded during region movement. Exclude file should<a name="line.207"></a>
-<span class="sourceLineNo">208</span>     * have 'host:port' per line. Port is mandatory here as we can have many RS running on a single<a name="line.208"></a>
-<span class="sourceLineNo">209</span>     * host.<a name="line.209"></a>
-<span class="sourceLineNo">210</span>     */<a name="line.210"></a>
-<span class="sourceLineNo">211</span>    public RegionMoverBuilder excludeFile(String excludefile) {<a name="line.211"></a>
-<span class="sourceLineNo">212</span>      this.excludeFile = excludefile;<a name="line.212"></a>
-<span class="sourceLineNo">213</span>      return this;<a name="line.213"></a>
-<span class="sourceLineNo">214</span>    }<a name="line.214"></a>
-<span class="sourceLineNo">215</span><a name="line.215"></a>
-<span class="sourceLineNo">216</span>    /**<a name="line.216"></a>
-<span class="sourceLineNo">217</span>     * Set the designated file. Designated file contains hostnames where region moves. Designated<a name="line.217"></a>
-<span class="sourceLineNo">218</span>     * file should have 'host:port' per line. Port is mandatory here as we can have many RS running<a name="line.218"></a>
-<span class="sourceLineNo">219</span>     * on a single host.<a name="line.219"></a>
-<span class="sourceLineNo">220</span>     * @param designatedFile The designated file<a name="line.220"></a>
-<span class="sourceLineNo">221</span>     * @return RegionMoverBuilder object<a name="line.221"></a>
-<span class="sourceLineNo">222</span>     */<a name="line.222"></a>
-<span class="sourceLineNo">223</span>    public RegionMoverBuilder designatedFile(String designatedFile) {<a name="line.223"></a>
-<span class="sourceLineNo">224</span>      this.designatedFile = designatedFile;<a name="line.224"></a>
-<span class="sourceLineNo">225</span>      return this;<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    }<a name="line.226"></a>
-<span class="sourceLineNo">227</span><a name="line.227"></a>
-<span class="sourceLineNo">228</span>    /**<a name="line.228"></a>
-<span class="sourceLineNo">229</span>     * Set ack/noAck mode.<a name="line.229"></a>
-<span class="sourceLineNo">230</span>     * &lt;p&gt;<a name="line.230"></a>
-<span class="sourceLineNo">231</span>     * In ack mode regions are acknowledged before and after moving and the move is retried<a name="line.231"></a>
-<span class="sourceLineNo">232</span>     * hbase.move.retries.max times, if unsuccessful we quit with exit code 1.No Ack mode is a best<a name="line.232"></a>
-<span class="sourceLineNo">233</span>     * effort mode,each region movement is tried once.This can be used during graceful shutdown as<a name="line.233"></a>
-<span class="sourceLineNo">234</span>     * even if we have a stuck region,upon shutdown it'll be reassigned anyway.<a name="line.234"></a>
-<span class="sourceLineNo">235</span>     * &lt;p&gt;<a name="line.235"></a>
-<span class="sourceLineNo">236</span>     * n * @return RegionMoverBuilder object<a name="line.236"></a>
-<span class="sourceLineNo">237</span>     */<a name="line.237"></a>
-<span class="sourceLineNo">238</span>    public RegionMoverBuilder ack(boolean ack) {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>      this.ack = ack;<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      return this;<a name="line.240"></a>
-<span class="sourceLineNo">241</span>    }<a name="line.241"></a>
-<span class="sourceLineNo">242</span><a name="line.242"></a>
-<span class="sourceLineNo">243</span>    /**<a name="line.243"></a>
-<span class="sourceLineNo">244</span>     * Set the timeout for Load/Unload operation in seconds.This is a global timeout,threadpool for<a name="line.244"></a>
-<span class="sourceLineNo">245</span>     * movers also have a separate time which is hbase.move.wait.max * number of regions to<a name="line.245"></a>
-<span class="sourceLineNo">246</span>     * load/unload<a name="line.246"></a>
-<span class="sourceLineNo">247</span>     * @param timeout in seconds<a name="line.247"></a>
-<span class="sourceLineNo">248</span>     * @return RegionMoverBuilder object<a name="line.248"></a>
-<span class="sourceLineNo">249</span>     */<a name="line.249"></a>
-<span class="sourceLineNo">250</span>    public RegionMoverBuilder timeout(int timeout) {<a name="line.250"></a>
-<span class="sourceLineNo">251</span>      this.timeout = timeout;<a name="line.251"></a>
-<span class="sourceLineNo">252</span>      return this;<a name="line.252"></a>
-<span class="sourceLineNo">253</span>    }<a name="line.253"></a>
-<span class="sourceLineNo">254</span><a name="line.254"></a>
-<span class="sourceLineNo">255</span>    /**<a name="line.255"></a>
-<span class="sourceLineNo">256</span>     * Set specific rackManager implementation. This setter method is for testing purpose only.<a name="line.256"></a>
-<span class="sourceLineNo">257</span>     * @param rackManager rackManager impl<a name="line.257"></a>
-<span class="sourceLineNo">258</span>     * @return RegionMoverBuilder object<a name="line.258"></a>
-<span class="sourceLineNo">259</span>     */<a name="line.259"></a>
-<span class="sourceLineNo">260</span>    @InterfaceAudience.Private<a name="line.260"></a>
-<span class="sourceLineNo">261</span>    public RegionMoverBuilder rackManager(RackManager rackManager) {<a name="line.261"></a>
-<span class="sourceLineNo">262</span>      this.rackManager = rackManager;<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      return this;<a name="line.263"></a>
-<span class="sourceLineNo">264</span>    }<a name="line.264"></a>
-<span class="sourceLineNo">265</span><a name="line.265"></a>
-<span class="sourceLineNo">266</span>    /**<a name="line.266"></a>
-<span class="sourceLineNo">267</span>     * This method builds the appropriate RegionMover object which can then be used to load/unload<a name="line.267"></a>
-<span class="sourceLineNo">268</span>     * using load and unload methods<a name="line.268"></a>
-<span class="sourceLineNo">269</span>     * @return RegionMover object<a name="line.269"></a>
-<span class="sourceLineNo">270</span>     */<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    public RegionMover build() throws IOException {<a name="line.271"></a>
-<span class="sourceLineNo">272</span>      return new RegionMover(this);<a name="line.272"></a>
-<span class="sourceLineNo">273</span>    }<a name="line.273"></a>
-<span class="sourceLineNo">274</span>  }<a name="line.274"></a>
-<span class="sourceLineNo">275</span><a name="line.275"></a>
-<span class="sourceLineNo">276</span>  /**<a name="line.276"></a>
-<span class="sourceLineNo">277</span>   * Loads the specified {@link #hostname} with regions listed in the {@link #filename} RegionMover<a name="line.277"></a>
-<span class="sourceLineNo">278</span>   * Object has to be created using {@link #RegionMover(RegionMoverBuilder)}<a name="line.278"></a>
-<span class="sourceLineNo">279</span>   * @return true if loading succeeded, false otherwise<a name="line.279"></a>
-<span class="sourceLineNo">280</span>   */<a name="line.280"></a>
-<span class="sourceLineNo">281</span>  public boolean load() throws ExecutionException, InterruptedException, TimeoutException {<a name="line.281"></a>
-<span class="sourceLineNo">282</span>    ExecutorService loadPool = Executors.newFixedThreadPool(1);<a name="line.282"></a>
-<span class="sourceLineNo">283</span>    Future&lt;Boolean&gt; loadTask = loadPool.submit(getMetaRegionMovePlan());<a name="line.283"></a>
-<span class="sourceLineNo">284</span>    boolean isMetaMoved = waitTaskToFinish(loadPool, loadTask, "loading");<a name="line.284"></a>
-<span class="sourceLineNo">285</span>    if (!isMetaMoved) {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      return false;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    loadPool = Executors.newFixedThreadPool(1);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>    loadTask = loadPool.submit(getNonMetaRegionsMovePlan());<a name="line.289"></a>
-<span class="sourceLineNo">290</span>    return waitTaskToFinish(loadPool, loadTask, "loading");<a name="line.290"></a>
-<span class="sourceLineNo">291</span>  }<a name="line.291"></a>
-<span class="sourceLineNo">292</span><a name="line.292"></a>
-<span class="sourceLineNo">293</span>  private Callable&lt;Boolean&gt; getMetaRegionMovePlan() {<a name="line.293"></a>
-<span class="sourceLineNo">294</span>    return getRegionsMovePlan(true);<a name="line.294"></a>
-<span class="sourceLineNo">295</span>  }<a name="line.295"></a>
-<span class="sourceLineNo">296</span><a name="line.296"></a>
-<span class="sourceLineNo">297</span>  private Callable&lt;Boolean&gt; getNonMetaRegionsMovePlan() {<a name="line.297"></a>
-<span class="sourceLineNo">298</span>    return getRegionsMovePlan(false);<a name="line.298"></a>
-<span class="sourceLineNo">299</span>  }<a name="line.299"></a>
-<span class="sourceLineNo">300</span><a name="line.300"></a>
-<span class="sourceLineNo">301</span>  private Callable&lt;Boolean&gt; getRegionsMovePlan(boolean moveMetaRegion) {<a name="line.301"></a>
-<span class="sourceLineNo">302</span>    return () -&gt; {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>      try {<a name="line.303"></a>
-<span class="sourceLineNo">304</span>        List&lt;RegionInfo&gt; regionsToMove = readRegionsFromFile(filename);<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        if (regionsToMove.isEmpty()) {<a name="line.305"></a>
-<span class="sourceLineNo">306</span>          LOG.info("No regions to load.Exiting");<a name="line.306"></a>
-<span class="sourceLineNo">307</span>          return true;<a name="line.307"></a>
-<span class="sourceLineNo">308</span>        }<a name="line.308"></a>
-<span class="sourceLineNo">309</span>        Optional&lt;RegionInfo&gt; metaRegion = getMetaRegionInfoIfToBeMoved(regionsToMove);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>        if (moveMetaRegion) {<a name="line.310"></a>
-<span class="sourceLineNo">311</span>          if (metaRegion.isPresent()) {<a name="line.311"></a>
-<span class="sourceLineNo">312</span>            loadRegions(Collections.singletonList(metaRegion.get()));<a name="line.312"></a>
-<span class="sourceLineNo">313</span>          }<a name="line.313"></a>
-<span class="sourceLineNo">314</span>        } else {<a name="line.314"></a>
-<span class="sourceLineNo">315</span>          metaRegion.ifPresent(regionsToMove::remove);<a name="line.315"></a>
-<span class="sourceLineNo">316</span>          loadRegions(regionsToMove);<a name="line.316"></a>
-<span class="sourceLineNo">317</span>        }<a name="line.317"></a>
-<span class="sourceLineNo">318</span>      } catch (Exception e) {<a name="line.318"></a>
-<span class="sourceLineNo">319</span>        LOG.error("Error while loading regions to " + hostname, e);<a name="line.319"></a>
-<span class="sourceLineNo">320</span>        return false;<a name="line.320"></a>
-<span class="sourceLineNo">321</span>      }<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      return true;<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    };<a name="line.323"></a>
-<span class="sourceLineNo">324</span>  }<a name="line.324"></a>
-<span class="sourceLineNo">325</span><a name="line.325"></a>
-<span class="sourceLineNo">326</span>  private Optional&lt;RegionInfo&gt; getMetaRegionInfoIfToBeMoved(List&lt;RegionInfo&gt; regionsToMove) {<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    return regionsToMove.stream().filter(RegionInfo::isMetaRegion).findFirst();<a name="line.327"></a>
-<span class="sourceLineNo">328</span>  }<a name="line.328"></a>
-<span class="sourceLineNo">329</span><a name="line.329"></a>
-<span class="sourceLineNo">330</span>  private void loadRegions(List&lt;RegionInfo&gt; regionsToMove) throws Exception {<a name="line.330"></a>
-<span class="sourceLineNo">331</span>    ServerName server = getTargetServer();<a name="line.331"></a>
-<span class="sourceLineNo">332</span>    List&lt;RegionInfo&gt; movedRegions = Collections.synchronizedList(new ArrayList&lt;&gt;());<a name="line.332"></a>
-<span class="sourceLineNo">333</span>    LOG.info("Moving " + regionsToMove.size() + " regions to " + server + " using "<a name="line.333"></a>
-<span class="sourceLineNo">334</span>      + this.maxthreads + " threads.Ack mode:" + this.ack);<a name="line.334"></a>
-<span class="sourceLineNo">335</span><a name="line.335"></a>
-<span class="sourceLineNo">336</span>    final ExecutorService moveRegionsPool = Executors.newFixedThreadPool(this.maxthreads);<a name="line.336"></a>
-<span class="sourceLineNo">337</span>    List&lt;Future&lt;Boolean&gt;&gt; taskList = new ArrayList&lt;&gt;();<a name="line.337"></a>
-<span class="sourceLineNo">338</span>    int counter = 0;<a name="line.338"></a>
-<span class="sourceLineNo">339</span>    while (counter &lt; regionsToMove.size()) {<a name="line.339"></a>
-<span class="sourceLineNo">340</span>      RegionInfo region = regionsToMove.get(counter);<a name="line.340"></a>
-<span class="sourceLineNo">341</span>      ServerName currentServer = MoveWithAck.getServerNameForRegion(region, admin, conn);<a name="line.341"></a>
-<span class="sourceLineNo">342</span>      if (currentServer == null) {<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        LOG<a name="line.343"></a>
-<span class="sourceLineNo">344</span>          .warn("Could not get server for Region:" + region.getRegionNameAsString() + " moving on");<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        counter++;<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        continue;<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      } else if (server.equals(currentServer)) {<a name="line.347"></a>
-<span class="sourceLineNo">348</span>        LOG.info(<a name="line.348"></a>
-<span class="sourceLineNo">349</span>          "Region " + region.getRegionNameAsString() + " is already on target server=" + server);<a name="line.349"></a>
-<span class="sourceLineNo">350</span>        counter++;<a name="line.350"></a>
-<span class="sourceLineNo">351</span>        continue;<a name="line.351"></a>
-<span class="sourceLineNo">352</span>      }<a name="line.352"></a>
-<span class="sourceLineNo">353</span>      if (ack) {<a name="line.353"></a>
-<span class="sourceLineNo">354</span>        Future&lt;Boolean&gt; task = moveRegionsPool<a name="line.354"></a>
-<span class="sourceLineNo">355</span>          .submit(new MoveWithAck(conn, region, currentServer, server, movedRegions));<a name="line.355"></a>
-<span class="sourceLineNo">356</span>        taskList.add(task);<a name="line.356"></a>
-<span class="sourceLineNo">357</span>      } else {<a name="line.357"></a>
-<span class="sourceLineNo">358</span>        Future&lt;Boolean&gt; task = moveRegionsPool<a name="line.358"></a>
-<span class="sourceLineNo">359</span>          .submit(new MoveWithoutAck(admin, region, currentServer, server, movedRegions));<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        taskList.add(task);<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      }<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      counter++;<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    }<a name="line.363"></a>
-<span class="sourceLineNo">364</span><a name="line.364"></a>
-<span class="sourceLineNo">365</span>    moveRegionsPool.shutdown();<a name="line.365"></a>
-<span class="sourceLineNo">366</span>    long timeoutInSeconds = regionsToMove.size()<a name="line.366"></a>
-<span class="sourceLineNo">367</span>      * admin.getConfiguration().getLong(MOVE_WAIT_MAX_KEY, DEFAULT_MOVE_WAIT_MAX);<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    waitMoveTasksToFinish(moveRegionsPool, taskList, timeoutInSeconds);<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  }<a name="line.369"></a>
-<span class="sourceLineNo">370</span><a name="line.370"></a>
-<span class="sourceLineNo">371</span>  /**<a name="line.371"></a>
-<span class="sourceLineNo">372</span>   * Unload regions from given {@link #hostname} using ack/noAck mode and {@link #maxthreads}.In<a name="line.372"></a>
-<span class="sourceLineNo">373</span>   * noAck mode we do not make sure that region is successfully online on the target region<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * server,hence it is best effort.We do not unload regions to hostnames given in<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * {@link #excludeFile}. If designatedFile is present with some contents, we will unload regions<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   * to hostnames provided in {@link #designatedFile}<a name="line.376"></a>
-<span class="sourceLineNo">377</span>   * @return true if unloading succeeded, false otherwise<a name="line.377"></a>
-<span class="sourceLineNo">378</span>   */<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  public boolean unload() throws InterruptedException, ExecutionException, TimeoutException {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    return unloadRegions(false);<a name="line.380"></a>
-<span class="sourceLineNo">381</span>  }<a name="line.381"></a>
-<span class="sourceLineNo">382</span><a name="line.382"></a>
-<span class="sourceLineNo">383</span>  /**<a name="line.383"></a>
-<span class="sourceLineNo">384</span>   * Unload regions from given {@link #hostname} using ack/noAck mode and {@link #maxthreads}.In<a name="line.384"></a>
-<span class="sourceLineNo">385</span>   * noAck mode we do not make sure that region is successfully online on the target region<a name="line.385"></a>
-<span class="sourceLineNo">386</span>   * server,hence it is best effort.We do not unload regions to hostnames given in<a name="line.386"></a>
-<span class="sourceLineNo">387</span>   * {@link #excludeFile}. If designatedFile is present with some contents, we will unload regions<a name="line.387"></a>
-<span class="sourceLineNo">388</span>   * to hostnames provided in {@link #designatedFile}. While unloading regions, destination<a name="line.388"></a>
-<span class="sourceLineNo">389</span>   * RegionServers are selected from different rack i.e regions should not move to any RegionServers<a name="line.389"></a>
-<span class="sourceLineNo">390</span>   * that belong to same rack as source RegionServer.<a name="line.390"></a>
-<span class="sourceLineNo">391</span>   * @return true if unloading succeeded, false otherwise<a name="line.391"></a>
-<span class="sourceLineNo">392</span>   */<a name="line.392"></a>
-<span class="sourceLineNo">393</span>  public boolean unloadFromRack()<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    throws InterruptedException, ExecutionException, TimeoutException {<a name="line.394"></a>
-<span class="sourceLineNo">395</span>    return unloadRegions(true);<a name="line.395"></a>
-<span class="sourceLineNo">396</span>  }<a name="line.396"></a>
-<span class="sourceLineNo">397</span><a name="line.397"></a>
-<span class="sourceLineNo">398</span>  private boolean unloadRegions(boolean unloadFromRack)<a name="line.398"></a>
-<span class="sourceLineNo">399</span>    throws InterruptedException, ExecutionException, TimeoutException {<a name="line.399"></a>
-<span class="sourceLineNo">400</span>    deleteFile(this.filename);<a name="line.400"></a>
-<span class="sourceLineNo">401</span>    ExecutorService unloadPool = Executors.newFixedThreadPool(1);<a name="line.401"></a>
-<span class="sourceLineNo">402</span>    Future&lt;Boolean&gt; unloadTask = unloadPool.submit(() -&gt; {<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      List&lt;RegionInfo&gt; movedRegions = Collections.synchronizedList(new ArrayList&lt;&gt;());<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      try {<a name="line.404"></a>
-<span class="sourceLineNo">405</span>        // Get Online RegionServers<a name="line.405"></a>
-<span class="sourceLineNo">406</span>        List&lt;ServerName&gt; regionServers = new ArrayList&lt;&gt;();<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        RSGroupInfo rsgroup = admin.getRSGroup(Address.fromParts(hostname, port));<a name="line.407"></a>
-<span class="sourceLineNo">408</span>        LOG.info("{} belongs to {}", hostname, rsgroup.getName());<a name="line.408"></a>
-<span class="sourceLineNo">409</span>        regionServers.addAll(filterRSGroupServers(rsgroup, admin.getRegionServers()));<a name="line.409"></a>
-<span class="sourceLineNo">410</span>        // Remove the host Region server from target Region Servers list<a name="line.410"></a>
-<span class="sourceLineNo">411</span>        ServerName server = stripServer(regionServers, hostname, port);<a name="line.411"></a>
-<span class="sourceLineNo">412</span>        if (server == null) {<a name="line.412"></a>
-<span class="sourceLineNo">413</span>          LOG.info("Could not find server '{}:{}' in the set of region servers. giving up.",<a name="line.413"></a>
-<span class="sourceLineNo">414</span>            hostname, port);<a name="line.414"></a>
-<span class="sourceLineNo">415</span>          LOG.debug("List of region servers: {}", regionServers);<a name="line.415"></a>
-<span class="sourceLineNo">416</span>          return false;<a name="line.416"></a>
-<span class="sourceLineNo">417</span>        }<a name="line.417"></a>
-<span class="sourceLineNo">418</span>        // Remove RS not present in the designated file<a name="line.418"></a>
-<span class="sourceLineNo">419</span>        includeExcludeRegionServers(designatedFile, regionServers, true);<a name="line.419"></a>
-<span class="sourceLineNo">420</span><a name="line.420"></a>
-<span class="sourceLineNo">421</span>        // Remove RS present in the exclude file<a name="line.421"></a>
-<span class="sourceLineNo">422</span>        includeExcludeRegionServers(excludeFile, regionServers, false);<a name="line.422"></a>
-<span class="sourceLineNo">423</span><a name="line.423"></a>
-<span class="sourceLineNo">424</span>        if (unloadFromRack) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>          // remove regionServers that belong to same rack (as source host) since the goal is to<a name="line.425"></a>
-<span class="sourceLineNo">426</span>          // unload regions from source regionServer to destination regionServers<a name="line.426"></a>
-<span class="sourceLineNo">427</span>          // that belong to different rack only.<a name="line.427"></a>
-<span class="sourceLineNo">428</span>          String sourceRack = rackManager.getRack(server);<a name="line.428"></a>
-<span class="sourceLineNo">429</span>          List&lt;String&gt; racks = rackManager.getRack(regionServers);<a name="line.429"></a>
-<span class="sourceLineNo">430</span>          Iterator&lt;ServerName&gt; iterator = regionServers.iterator();<a name="line.430"></a>
-<span class="sourceLineNo">431</span>          int i = 0;<a name="line.431"></a>
-<span class="sourceLineNo">432</span>          while (iterator.hasNext()) {<a name="line.432"></a>
-<span class="sourceLineNo">433</span>            iterator.next();<a name="line.433"></a>
-<span class="sourceLineNo">434</span>            if (racks.size() &gt; i &amp;&amp; racks.get(i) != null &amp;&amp; racks.get(i).equals(sourceRack)) {<a name="line.434"></a>
-<span class="sourceLineNo">435</span>              iterator.remove();<a name="line.435"></a>
-<span class="sourceLineNo">436</span>            }<a name="line.436"></a>
-<span class="sourceLineNo">437</span>            i++;<a name="line.437"></a>
-<span class="sourceLineNo">438</span>          }<a name="line.438"></a>
-<span class="sourceLineNo">439</span>        }<a name="line.439"></a>
-<span class="sourceLineNo">440</span><a name="line.440"></a>
-<span class="sourceLineNo">441</span>        // Remove decommissioned RS<a name="line.441"></a>
-<span class="sourceLineNo">442</span>        Set&lt;ServerName&gt; decommissionedRS = new HashSet&lt;&gt;(admin.listDecommissionedRegionServers());<a name="line.442"></a>
-<span class="sourceLineNo">443</span>        if (CollectionUtils.isNotEmpty(decommissionedRS)) {<a name="line.443"></a>
-<span class="sourceLineNo">444</span>          regionServers.removeIf(decommissionedRS::contains);<a name="line.444"></a>
-<span class="sourceLineNo">445</span>          LOG.debug("Excluded RegionServers from unloading regions to because they "<a name="line.445"></a>
-<span class="sourceLineNo">446</span>            + "are marked as decommissioned. Servers: {}", decommissionedRS);<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        }<a name="line.447"></a>
-<span class="sourceLineNo">448</span><a name="line.448"></a>
-<span class="sourceLineNo">449</span>        stripMaster(regionServers);<a name="line.449"></a>
-<span class="sourceLineNo">450</span>        if (regionServers.isEmpty()) {<a name="line.450"></a>
-<span class="sourceLineNo">451</span>          LOG.warn("No Regions were moved - no servers available");<a name="line.451"></a>
-<span class="sourceLineNo">452</span>          return false;<a name="line.452"></a>
-<span class="sourceLineNo">453</span>        } else {<a name="line.453"></a>
-<span class="sourceLineNo">454</span>          LOG.info("Available servers {}", regionServers);<a name="line.454"></a>
-<span class="sourceLineNo">455</span>        }<a name="line.455"></a>
-<span class="sourceLineNo">456</span>        unloadRegions(server, regionServers, movedRegions);<a name="line.456"></a>
-<span class="sourceLineNo">457</span>      } catch (Exception e) {<a name="line.457"></a>
-<span class="sourceLineNo">458</span>        LOG.error("Error while unloading regions ", e);<a name="line.458"></a>
-<span class="sourceLineNo">459</span>        return false;<a name="line.459"></a>
-<span class="sourceLineNo">460</span>      } finally {<a name="line.460"></a>
-<span class="sourceLineNo">461</span>        if (movedRegions != null) {<a name="line.461"></a>
-<span class="sourceLineNo">462</span>          writeFile(filename, movedRegions);<a name="line.462"></a>
-<span class="sourceLineNo">463</span>        }<a name="line.463"></a>
-<span class="sourceLineNo">464</span>      }<a name="line.464"></a>
-<span class="sourceLineNo">465</span>      return true;<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    });<a name="line.466"></a>
-<span class="sourceLineNo">467</span>    return waitTaskToFinish(unloadPool, unloadTask, "unloading");<a name="line.467"></a>
-<span class="sourceLineNo">468</span>  }<a name="line.468"></a>
-<span class="sourceLineNo">469</span><a name="line.469"></a>
-<span class="sourceLineNo">470</span>  @InterfaceAudience.Private<a name="line.470"></a>
-<span class="sourceLineNo">471</span>  Collection&lt;ServerName&gt; filterRSGroupServers(RSGroupInfo rsgroup,<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    Collection&lt;ServerName&gt; onlineServers) {<a name="line.472"></a>
-<span class="sourceLineNo">473</span>    if (rsgroup.getName().equals(RSGroupInfo.DEFAULT_GROUP)) {<a name="line.473"></a>
-<span class="sourceLineNo">474</span>      return onlineServers;<a name="line.474"></a>
-<span class="sourceLineNo">475</span>    }<a name="line.475"></a>
-<span class="sourceLineNo">476</span>    List&lt;ServerName&gt; serverLists = new ArrayList&lt;&gt;(rsgroup.getServers().size());<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    for (ServerName server : onlineServers) {<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      Address address = Address.fromParts(server.getHostname(), server.getPort());<a name="line.478"></a>
-<span class="sourceLineNo">479</span>      if (rsgroup.containsServer(address)) {<a name="line.479"></a>
-<span class="sourceLineNo">480</span>        serverLists.add(server);<a name="line.480"></a>
-<span class="sourceLineNo">481</span>      }<a name="line.481"></a>
-<span class="sourceLineNo">482</span>    }<a name="line.482"></a>
-<span class="sourceLineNo">483</span>    return serverLists;<a name="line.483"></a>
-<span class="sourceLineNo">484</span>  }<a name="line.484"></a>
-<span class="sourceLineNo">485</span><a name="line.485"></a>
-<span class="sourceLineNo">486</span>  private void unloadRegions(ServerName server, List&lt;ServerName&gt; regionServers,<a name="line.486"></a>
-<span class="sourceLineNo">487</span>    List&lt;RegionInfo&gt; movedRegions) throws Exception {<a name="line.487"></a>
-<span class="sourceLineNo">488</span>    while (true) {<a name="line.488"></a>
-<span class="sourceLineNo">489</span>      List&lt;RegionInfo&gt; regionsToMove = admin.getRegions(server);<a name="line.489"></a>
-<span class="sourceLineNo">490</span>      regionsToMove.removeAll(movedRegions);<a name="line.490"></a>
-<span class="sourceLineNo">491</span>      if (regionsToMove.isEmpty()) {<a name="line.491"></a>
-<span class="sourceLineNo">492</span>        LOG.info("No Regions to move....Quitting now");<a name="line.492"></a>
-<span class="sourceLineNo">493</span>        break;<a name="line.493"></a>
+<span class="sourceLineNo">176</span>    private static Configuration createConf() {<a name="line.176"></a>
+<span class="sourceLineNo">177</span>      Configuration conf = HBaseConfiguration.create();<a name="line.177"></a>
+<span class="sourceLineNo">178</span>      conf.setInt("hbase.client.prefetch.limit", 1);<a name="line.178"></a>
+<span class="sourceLineNo">179</span>      conf.setInt("hbase.client.pause", 500);<a name="line.179"></a>
+<span class="sourceLineNo">180</span>      conf.setInt("hbase.client.retries.number", 100);<a name="line.180"></a>
+<span class="sourceLineNo">181</span>      return conf;<a name="line.181"></a>
+<span class="sourceLineNo">182</span>    }<a name="line.182"></a>
+<span class="sourceLineNo">183</span><a name="line.183"></a>
+<span class="sourceLineNo">184</span>    /**<a name="line.184"></a>
+<span class="sourceLineNo">185</span>     * @param hostname Hostname to unload regions from or load regions to. Can be either hostname or<a name="line.185"></a>
+<span class="sourceLineNo">186</span>     *                 hostname:port.<a name="line.186"></a>
+<span class="sourceLineNo">187</span>     * @param conf     Configuration object<a name="line.187"></a>
+<span class="sourceLineNo">188</span>     */<a name="line.188"></a>
+<span class="sourceLineNo">189</span>    public RegionMoverBuilder(String hostname, Configuration conf) {<a name="line.189"></a>
+<span class="sourceLineNo">190</span>      String[] splitHostname = hostname.toLowerCase().split(":");<a name="line.190"></a>
+<span class="sourceLineNo">191</span>      this.hostname = splitHostname[0];<a name="line.191"></a>
+<span class="sourceLineNo">192</span>      if (splitHostname.length == 2) {<a name="line.192"></a>
+<span class="sourceLineNo">193</span>        this.port = Integer.parseInt(splitHostname[1]);<a name="line.193"></a>
+<span class="sourceLineNo">194</span>      } else {<a name="line.194"></a>
+<span class="sourceLineNo">195</span>        this.port = conf.getInt(HConstants.REGIONSERVER_PORT, HConstants.DEFAULT_REGIONSERVER_PORT);<a name="line.195"></a>
+<span class="sourceLineNo">196</span>      }<a name="line.196"></a>
+<span class="sourceLineNo">197</span>      this.filename = defaultDir + File.separator + System.getProperty("user.name") + this.hostname<a name="line.197"></a>
+<span class="sourceLineNo">198</span>        + ":" + Integer.toString(this.port);<a name="line.198"></a>
+<span class="sourceLineNo">199</span>      this.conf = conf;<a name="line.199"></a>
+<span class="sourceLineNo">200</span>    }<a name="line.200"></a>
+<span class="sourceLineNo">201</span><a name="line.201"></a>
+<span class="sourceLineNo">202</span>    /**<a name="line.202"></a>
+<span class="sourceLineNo">203</span>     * Path of file where regions will be written to during unloading/read from during loading n<a name="line.203"></a>
+<span class="sourceLineNo">204</span>     * * @return RegionMoverBuilder object<a name="line.204"></a>
+<span class="sourceLineNo">205</span>     */<a name="line.205"></a>
+<span class="sourceLineNo">206</span>    public RegionMoverBuilder filename(String filename) {<a name="line.206"></a>
+<span class="sourceLineNo">207</span>      this.filename = filename;<a name="line.207"></a>
+<span class="sourceLineNo">208</span>      return this;<a name="line.208"></a>
+<span class="sourceLineNo">209</span>    }<a name="line.209"></a>
+<span class="sourceLineNo">210</span><a name="line.210"></a>
+<span class="sourceLineNo">211</span>    /**<a name="line.211"></a>
+<span class="sourceLineNo">212</span>     * Set the max number of threads that will be used to move regions<a name="line.212"></a>
+<span class="sourceLineNo">213</span>     */<a name="line.213"></a>
+<span class="sourceLineNo">214</span>    public RegionMoverBuilder maxthreads(int threads) {<a name="line.214"></a>
+<span class="sourceLineNo">215</span>      this.maxthreads = threads;<a name="line.215"></a>
+<span class="sourceLineNo">216</span>      return this;<a name="line.216"></a>
+<span class="sourceLineNo">217</span>    }<a name="line.217"></a>
+<span class="sourceLineNo">218</span><a name="line.218"></a>
+<span class="sourceLineNo">219</span>    /**<a name="line.219"></a>
+<span class="sourceLineNo">220</span>     * Path of file containing hostnames to be excluded during region movement. Exclude file should<a name="line.220"></a>
+<span class="sourceLineNo">221</span>     * have 'host:port' per line. Port is mandatory here as we can have many RS running on a single<a name="line.221"></a>
+<span class="sourceLineNo">222</span>     * host.<a name="line.222"></a>
+<span class="sourceLineNo">223</span>     */<a name="line.223"></a>
+<span class="sourceLineNo">224</span>    public RegionMoverBuilder excludeFile(String excludefile) {<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      this.excludeFile = excludefile;<a name="line.225"></a>
+<span class="sourceLineNo">226</span>      return this;<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    }<a name="line.227"></a>
+<span class="sourceLineNo">228</span><a name="line.228"></a>
+<span class="sourceLineNo">229</span>    /**<a name="line.229"></a>
+<span class="sourceLineNo">230</span>     * Set the designated file. Designated file contains hostnames where region moves. Designated<a name="line.230"></a>
+<span class="sourceLineNo">231</span>     * file should have 'host:port' per line. Port is mandatory here as we can have many RS running<a name="line.231"></a>
+<span class="sourceLineNo">232</span>     * on a single host.<a name="line.232"></a>
+<span class="sourceLineNo">233</span>     * @param designatedFile The designated file<a name="line.233"></a>
+<span class="sourceLineNo">234</span>     * @return RegionMoverBuilder object<a name="line.234"></a>
+<span class="sourceLineNo">235</span>     */<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    public RegionMoverBuilder designatedFile(String designatedFile) {<a name="line.236"></a>
+<span class="sourceLineNo">237</span>      this.designatedFile = designatedFile;<a name="line.237"></a>
+<span class="sourceLineNo">238</span>      return this;<a name="line.238"></a>
+<span class="sourceLineNo">239</span>    }<a name="line.239"></a>
+<span class="sourceLineNo">240</span><a name="line.240"></a>
+<span class="sourceLineNo">241</span>    /**<a name="line.241"></a>
+<span class="sourceLineNo">242</span>     * Set ack/noAck mode.<a name="line.242"></a>
+<span class="sourceLineNo">243</span>     * &lt;p&gt;<a name="line.243"></a>
+<span class="sourceLineNo">244</span>     * In ack mode regions are acknowledged before and after moving and the move is retried<a name="line.244"></a>
+<span class="sourceLineNo">245</span>     * hbase.move.retries.max times, if unsuccessful we quit with exit code 1.No Ack mode is a best<a name="line.245"></a>
+<span class="sourceLineNo">246</span>     * effort mode,each region movement is tried once.This can be used during graceful shutdown as<a name="line.246"></a>
+<span class="sourceLineNo">247</span>     * even if we have a stuck region,upon shutdown it'll be reassigned anyway.<a name="line.247"></a>
+<span class="sourceLineNo">248</span>     * &lt;p&gt;<a name="line.248"></a>
+<span class="sourceLineNo">249</span>     * n * @return RegionMoverBuilder object<a name="line.249"></a>
+<span class="sourceLineNo">250</span>     */<a name="line.250"></a>
+<span class="sourceLineNo">251</span>    public RegionMoverBuilder ack(boolean ack) {<a name="line.251"></a>
+<span class="sourceLineNo">252</span>      this.ack = ack;<a name="line.252"></a>
+<span class="sourceLineNo">253</span>      return this;<a name="line.253"></a>
+<span class="sourceLineNo">254</span>    }<a name="line.254"></a>
+<span class="sourceLineNo">255</span><a name="line.255"></a>
+<span class="sourceLineNo">256</span>    /**<a name="line.256"></a>
+<span class="sourceLineNo">257</span>     * Set the timeout for Load/Unload operation in seconds.This is a global timeout,threadpool for<a name="line.257"></a>
+<span class="sourceLineNo">258</span>     * movers also have a separate time which is hbase.move.wait.max * number of regions to<a name="line.258"></a>
+<span class="sourceLineNo">259</span>     * load/unload<a name="line.259"></a>
+<span class="sourceLineNo">260</span>     * @param timeout in seconds<a name="line.260"></a>
+<span class="sourceLineNo">261</span>     * @return RegionMoverBuilder object<a name="line.261"></a>
+<span class="sourceLineNo">262</span>     */<a name="line.262"></a>
+<span class="sourceLineNo">263</span>    public RegionMoverBuilder timeout(int timeout) {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>      this.timeout = timeout;<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      return this;<a name="line.265"></a>
+<span class="sourceLineNo">266</span>    }<a name="line.266"></a>
+<span class="sourceLineNo">267</span><a name="line.267"></a>
+<span class="sourceLineNo">268</span>    /**<a name="line.268"></a>
+<span class="sourceLineNo">269</span>     * Set specific rackManager implementation. This setter method is for testing purpose only.<a name="line.269"></a>
+<span class="sourceLineNo">270</span>     * @param rackManager rackManager impl<a name="line.270"></a>
+<span class="sourceLineNo">271</span>     * @return RegionMoverBuilder object<a name="line.271"></a>
+<span class="sourceLineNo">272</span>     */<a name="line.272"></a>
+<span class="sourceLineNo">273</span>    @InterfaceAudience.Private<a name="line.273"></a>
+<span class="sourceLineNo">274</span>    public RegionMoverBuilder rackManager(RackManager rackManager) {<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      this.rackManager = rackManager;<a name="line.275"></a>
+<span class="sourceLineNo">276</span>      return this;<a name="line.276"></a>
+<span class="sourceLineNo">277</span>    }<a name="line.277"></a>
+<span class="sourceLineNo">278</span><a name="line.278"></a>
+<span class="sourceLineNo">279</span>    /**<a name="line.279"></a>
+<span class="sourceLineNo">280</span>     * This method builds the appropriate RegionMover object which can then be used to load/unload<a name="line.280"></a>
+<span class="sourceLineNo">281</span>     * using load and unload methods<a name="line.281"></a>
+<span class="sourceLineNo">282</span>     * @return RegionMover object<a name="line.282"></a>
+<span class="sourceLineNo">283</span>     */<a name="line.283"></a>
+<span class="sourceLineNo">284</span>    public RegionMover build() throws IOException {<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      return new RegionMover(this);<a name="line.285"></a>
+<span class="sourceLineNo">286</span>    }<a name="line.286"></a>
+<span class="sourceLineNo">287</span>  }<a name="line.287"></a>
+<span class="sourceLineNo">288</span><a name="line.288"></a>
+<span class="sourceLineNo">289</span>  /**<a name="line.289"></a>
+<span class="sourceLineNo">290</span>   * Loads the specified {@link #hostname} with regions listed in the {@link #filename} RegionMover<a name="line.290"></a>
+<span class="sourceLineNo">291</span>   * Object has to be created using {@link #RegionMover(RegionMoverBuilder)}<a name="line.291"></a>
+<span class="sourceLineNo">292</span>   * @return true if loading succeeded, false otherwise<a name="line.292"></a>
+<span class="sourceLineNo">293</span>   */<a name="line.293"></a>
+<span class="sourceLineNo">294</span>  public boolean load() throws ExecutionException, InterruptedException, TimeoutException {<a name="line.294"></a>
+<span class="sourceLineNo">295</span>    ExecutorService loadPool = Executors.newFixedThreadPool(1);<a name="line.295"></a>
+<span class="sourceLineNo">296</span>    Future&lt;Boolean&gt; loadTask = loadPool.submit(getMetaRegionMovePlan());<a name="line.296"></a>
+<span class="sourceLineNo">297</span>    boolean isMetaMoved = waitTaskToFinish(loadPool, loadTask, "loading");<a name="line.297"></a>
+<span class="sourceLineNo">298</span>    if (!isMetaMoved) {<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      return false;<a name="line.299"></a>
+<span class="sourceLineNo">300</span>    }<a name="line.300"></a>
+<span class="sourceLineNo">301</span>    loadPool = Executors.newFixedThreadPool(1);<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    loadTask = loadPool.submit(getNonMetaRegionsMovePlan());<a name="line.302"></a>
+<span class="sourceLineNo">303</span>    return waitTaskToFinish(loadPool, loadTask, "loading");<a name="line.303"></a>
+<span class="sourceLineNo">304</span>  }<a name="line.304"></a>
+<span class="sourceLineNo">305</span><a name="line.305"></a>
+<span class="sourceLineNo">306</span>  private Callable&lt;Boolean&gt; getMetaRegionMovePlan() {<a name="line.306"></a>
+<span class="sourceLineNo">307</span>    return getRegionsMovePlan(true);<a name="line.307"></a>
+<span class="sourceLineNo">308</span>  }<a name="line.308"></a>
+<span class="sourceLineNo">309</span><a name="line.309"></a>
+<span class="sourceLineNo">310</span>  private Callable&lt;Boolean&gt; getNonMetaRegionsMovePlan() {<a name="line.310"></a>
+<span class="sourceLineNo">311</span>    return getRegionsMovePlan(false);<a name="line.311"></a>
+<span class="sourceLineNo">312</span>  }<a name="line.312"></a>
+<span class="sourceLineNo">313</span><a name="line.313"></a>
+<span class="sourceLineNo">314</span>  private Callable&lt;Boolean&gt; getRegionsMovePlan(boolean moveMetaRegion) {<a name="line.314"></a>
+<span class="sourceLineNo">315</span>    return () -&gt; {<a name="line.315"></a>
+<span class="sourceLineNo">316</span>      try {<a name="line.316"></a>
+<span class="sourceLineNo">317</span>        List&lt;RegionInfo&gt; regionsToMove = readRegionsFromFile(filename);<a name="line.317"></a>
+<span class="sourceLineNo">318</span>        if (regionsToMove.isEmpty()) {<a name="line.318"></a>
+<span class="sourceLineNo">319</span>          LOG.info("No regions to load.Exiting");<a name="line.319"></a>
+<span class="sourceLineNo">320</span>          return true;<a name="line.320"></a>
+<span class="sourceLineNo">321</span>        }<a name="line.321"></a>
+<span class="sourceLineNo">322</span>        Optional&lt;RegionInfo&gt; metaRegion = getMetaRegionInfoIfToBeMoved(regionsToMove);<a name="line.322"></a>
+<span class="sourceLineNo">323</span>        if (moveMetaRegion) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>          if (metaRegion.isPresent()) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>            loadRegions(Collections.singletonList(metaRegion.get()));<a name="line.325"></a>
+<span class="sourceLineNo">326</span>          }<a name="line.326"></a>
+<span class="sourceLineNo">327</span>        } else {<a name="line.327"></a>
+<span class="sourceLineNo">328</span>          metaRegion.ifPresent(regionsToMove::remove);<a name="line.328"></a>
+<span class="sourceLineNo">329</span>          loadRegions(regionsToMove);<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        }<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      } catch (Exception e) {<a name="line.331"></a>
+<span class="sourceLineNo">332</span>        LOG.error("Error while loading regions to " + hostname, e);<a name="line.332"></a>
+<span class="sourceLineNo">333</span>        return false;<a name="line.333"></a>
+<span class="sourceLineNo">334</span>      }<a name="line.334"></a>
+<span class="sourceLineNo">335</span>      return true;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    };<a name="line.336"></a>
+<span class="sourceLineNo">337</span>  }<a name="line.337"></a>
+<span class="sourceLineNo">338</span><a name="line.338"></a>
+<span class="sourceLineNo">339</span>  private Optional&lt;RegionInfo&gt; getMetaRegionInfoIfToBeMoved(List&lt;RegionInfo&gt; regionsToMove) {<a name="line.339"></a>
+<span class="sourceLineNo">340</span>    return regionsToMove.stream().filter(RegionInfo::isMetaRegion).findFirst();<a name="line.340"></a>
+<span class="sourceLineNo">341</span>  }<a name="line.341"></a>
+<span class="sourceLineNo">342</span><a name="line.342"></a>
+<span class="sourceLineNo">343</span>  private void loadRegions(List&lt;RegionInfo&gt; regionsToMove) throws Exception {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>    ServerName server = getTargetServer();<a name="line.344"></a>
+<span class="sourceLineNo">345</span>    List&lt;RegionInfo&gt; movedRegions = Collections.synchronizedList(new ArrayList&lt;&gt;());<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    LOG.info("Moving " + regionsToMove.size() + " regions to " + server + " using "<a name="line.346"></a>
+<span class="sourceLineNo">347</span>      + this.maxthreads + " threads.Ack mode:" + this.ack);<a name="line.347"></a>
+<span class="sourceLineNo">348</span><a name="line.348"></a>
+<span class="sourceLineNo">349</span>    final ExecutorService moveRegionsPool = Executors.newFixedThreadPool(this.maxthreads);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>    List&lt;Future&lt;Boolean&gt;&gt; taskList = new ArrayList&lt;&gt;();<a name="line.350"></a>
+<span class="sourceLineNo">351</span>    int counter = 0;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>    while (counter &lt; regionsToMove.size()) {<a name="line.352"></a>
+<span class="sourceLineNo">353</span>      RegionInfo region = regionsToMove.get(counter);<a name="line.353"></a>
+<span class="sourceLineNo">354</span>      ServerName currentServer = MoveWithAck.getServerNameForRegion(region, admin, conn);<a name="line.354"></a>
+<span class="sourceLineNo">355</span>      if (currentServer == null) {<a name="line.355"></a>
+<span class="sourceLineNo">356</span>        LOG<a name="line.356"></a>
+<span class="sourceLineNo">357</span>          .warn("Could not get server for Region:" + region.getRegionNameAsString() + " moving on");<a name="line.357"></a>
+<span class="sourceLineNo">358</span>        counter++;<a name="line.358"></a>
+<span class="sourceLineNo">359</span>        continue;<a name="line.359"></a>
+<span class="sourceLineNo">360</span>      } else if (server.equals(currentServer)) {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>        LOG.info(<a name="line.361"></a>
+<span class="sourceLineNo">362</span>          "Region " + region.getRegionNameAsString() + " is already on target server=" + server);<a name="line.362"></a>
+<span class="sourceLineNo">363</span>        counter++;<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        continue;<a name="line.364"></a>
+<span class="sourceLineNo">365</span>      }<a name="line.365"></a>
+<span class="sourceLineNo">366</span>      if (ack) {<a name="line.366"></a>
+<span class="sourceLineNo">367</span>        Future&lt;Boolean&gt; task = moveRegionsPool<a name="line.367"></a>
+<span class="sourceLineNo">368</span>          .submit(new MoveWithAck(conn, region, currentServer, server, movedRegions));<a name="line.368"></a>
+<span class="sourceLineNo">369</span>        taskList.add(task);<a name="line.369"></a>
+<span class="sourceLineNo">370</span>      } else {<a name="line.370"></a>
+<span class="sourceLineNo">371</span>        Future&lt;Boolean&gt; task = moveRegionsPool<a name="line.371"></a>
+<span class="sourceLineNo">372</span>          .submit(new MoveWithoutAck(admin, region, currentServer, server, movedRegions));<a name="line.372"></a>
+<span class="sourceLineNo">373</span>        taskList.add(task);<a name="line.373"></a>
+<span class="sourceLineNo">374</span>      }<a name="line.374"></a>
+<span class="sourceLineNo">375</span>      counter++;<a name="line.375"></a>
+<span class="sourceLineNo">376</span>    }<a name="line.376"></a>
+<span class="sourceLineNo">377</span><a name="line.377"></a>
+<span class="sourceLineNo">378</span>    moveRegionsPool.shutdown();<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    long timeoutInSeconds = regionsToMove.size()<a name="line.379"></a>
+<span class="sourceLineNo">380</span>      * admin.getConfiguration().getLong(MOVE_WAIT_MAX_KEY, DEFAULT_MOVE_WAIT_MAX);<a name="line.380"></a>
+<span class="sourceLineNo">381</span>    waitMoveTasksToFinish(moveRegionsPool, taskList, timeoutInSeconds);<a name="line.381"></a>
+<span class="sourceLineNo">382</span>  }<a name="line.382"></a>
+<span class="sourceLineNo">383</span><a name="line.383"></a>
+<span class="sourceLineNo">384</span>  /**<a name="line.384"></a>
+<span class="sourceLineNo">385</span>   * Unload regions from given {@link #hostname} using ack/noAck mode and {@link #maxthreads}.In<a name="line.385"></a>
+<span class="sourceLineNo">386</span>   * noAck mode we do not make sure that region is successfully online on the target region<a name="line.386"></a>
+<span class="sourceLineNo">387</span>   * server,hence it is best effort.We do not unload regions to hostnames given in<a name="line.387"></a>
+<span class="sourceLineNo">388</span>   * {@link #excludeFile}. If designatedFile is present with some contents, we will unload regions<a name="line.388"></a>
+<span class="sourceLineNo">389</span>   * to hostnames provided in {@link #designatedFile}<a name="line.389"></a>
+<span class="sourceLineNo">390</span>   * @return true if unloading succeeded, false otherwise<a name="line.390"></a>
+<span class="sourceLineNo">391</span>   */<a name="line.391"></a>
+<span class="sourceLineNo">392</span>  public boolean unload() throws InterruptedException, ExecutionException, TimeoutException {<a name="line.392"></a>
+<span class="sourceLineNo">393</span>    return unloadRegions(false);<a name="line.393"></a>
+<span class="sourceLineNo">394</span>  }<a name="line.394"></a>
+<span class="sourceLineNo">395</span><a name="line.395"></a>
+<span class="sourceLineNo">396</span>  /**<a name="line.396"></a>
+<span class="sourceLineNo">397</span>   * Unload regions from given {@link #hostname} using ack/noAck mode and {@link #maxthreads}.In<a name="line.397"></a>
+<span class="sourceLineNo">398</span>   * noAck mode we do not make sure that region is successfully online on the target region<a name="line.398"></a>
+<span class="sourceLineNo">399</span>   * server,hence it is best effort.We do not unload regions to hostnames given in<a name="line.399"></a>
+<span class="sourceLineNo">400</span>   * {@link #excludeFile}. If designatedFile is present with some contents, we will unload regions<a name="line.400"></a>
+<span class="sourceLineNo">401</span>   * to hostnames provided in {@link #designatedFile}. While unloading regions, destination<a name="line.401"></a>
+<span class="sourceLineNo">402</span>   * RegionServers are selected from different rack i.e regions should not move to any RegionServers<a name="line.402"></a>
+<span class="sourceLineNo">403</span>   * that belong to same rack as source RegionServer.<a name="line.403"></a>
+<span class="sourceLineNo">404</span>   * @return true if unloading succeeded, false otherwise<a name="line.404"></a>
+<span class="sourceLineNo">405</span>   */<a name="line.405"></a>
+<span class="sourceLineNo">406</span>  public boolean unloadFromRack()<a name="line.406"></a>
+<span class="sourceLineNo">407</span>    throws InterruptedException, ExecutionException, TimeoutException {<a name="line.407"></a>
+<span class="sourceLineNo">408</span>    return unloadRegions(true);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>  }<a name="line.409"></a>
+<span class="sourceLineNo">410</span><a name="line.410"></a>
+<span class="sourceLineNo">411</span>  private boolean unloadRegions(boolean unloadFromRack)<a name="line.411"></a>
+<span class="sourceLineNo">412</span>    throws InterruptedException, ExecutionException, TimeoutException {<a name="line.412"></a>
+<span class="sourceLineNo">413</span>    deleteFile(this.filename);<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    ExecutorService unloadPool = Executors.newFixedThreadPool(1);<a name="line.414"></a>
+<span class="sourceLineNo">415</span>    Future&lt;Boolean&gt; unloadTask = unloadPool.submit(() -&gt; {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>      List&lt;RegionInfo&gt; movedRegions = Collections.synchronizedList(new ArrayList&lt;&gt;());<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      try {<a name="line.417"></a>
+<span class="sourceLineNo">418</span>        // Get Online RegionServers<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        List&lt;ServerName&gt; regionServers = new ArrayList&lt;&gt;();<a name="line.419"></a>
+<span class="sourceLineNo">420</span>        RSGroupInfo rsgroup = admin.getRSGroup(Address.fromParts(hostname, port));<a name="line.420"></a>
+<span class="sourceLineNo">421</span>        LOG.info("{} belongs to {}", hostname, rsgroup.getName());<a name="line.421"></a>
+<span class="sourceLineNo">422</span>        regionServers.addAll(filterRSGroupServers(rsgroup, admin.getRegionServers()));<a name="line.422"></a>
+<span class="sourceLineNo">423</span>        // Remove the host Region server from target Region Servers list<a name="line.423"></a>
+<span class="sourceLineNo">424</span>        ServerName server = stripServer(regionServers, hostname, port);<a name="line.424"></a>
+<span class="sourceLineNo">425</span>        if (server == null) {<a name="line.425"></a>
+<span class="sourceLineNo">426</span>          LOG.info("Could not find server '{}:{}' in the set of region servers. giving up.",<a name="line.426"></a>
+<span class="sourceLineNo">427</span>            hostname, port);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>          LOG.debug("List of region servers: {}", regionServers);<a name="line.428"></a>
+<span class="sourceLineNo">429</span>          return false;<a name="line.429"></a>
+<span class="sourceLineNo">430</span>        }<a name="line.430"></a>
+<span class="sourceLineNo">431</span>        // Remove RS not present in the designated file<a name="line.431"></a>
+<span class="sourceLineNo">432</span>        includeExcludeRegionServers(designatedFile, regionServers, true);<a name="line.432"></a>
+<span class="sourceLineNo">433</span><a name="line.433"></a>
+<span class="sourceLineNo">434</span>        // Remove RS present in the exclude file<a name="line.434"></a>
+<span class="sourceLineNo">435</span>        includeExcludeRegionServers(excludeFile, regionServers, false);<a name="line.435"></a>
+<span class="sourceLineNo">436</span><a name="line.436"></a>
+<span class="sourceLineNo">437</span>        if (unloadFromRack) {<a name="line.437"></a>
+<span class="sourceLineNo">438</span>          // remove regionServers that belong to same rack (as source host) since the goal is to<a name="line.438"></a>
+<span class="sourceLineNo">439</span>          // unload regions from source regionServer to destination regionServers<a name="line.439"></a>
+<span class="sourceLineNo">440</span>          // that belong to different rack only.<a name="line.440"></a>
+<span class="sourceLineNo">441</span>          String sourceRack = rackManager.getRack(server);<a name="line.441"></a>
+<span class="sourceLineNo">442</span>          List&lt;String&gt; racks = rackManager.getRack(regionServers);<a name="line.442"></a>
+<span class="sourceLineNo">443</span>          Iterator&lt;ServerName&gt; iterator = regionServers.iterator();<a name="line.443"></a>
+<span class="sourceLineNo">444</span>          int i = 0;<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          while (iterator.hasNext()) {<a name="line.445"></a>
+<span class="sourceLineNo">446</span>            iterator.next();<a name="line.446"></a>
+<span class="sourceLineNo">447</span>            if (racks.size() &gt; i &amp;&amp; racks.get(i) != null &amp;&amp; racks.get(i).equals(sourceRack)) {<a name="line.447"></a>
+<span class="sourceLineNo">448</span>              iterator.remove();<a name="line.448"></a>
+<span class="sourceLineNo">449</span>            }<a name="line.449"></a>
+<span class="sourceLineNo">450</span>            i++;<a name="line.450"></a>
+<span class="sourceLineNo">451</span>          }<a name="line.451"></a>
+<span class="sourceLineNo">452</span>        }<a name="line.452"></a>
+<span class="sourceLineNo">453</span><a name="line.453"></a>
+<span class="sourceLineNo">454</span>        // Remove decommissioned RS<a name="line.454"></a>
+<span class="sourceLineNo">455</span>        Set&lt;ServerName&gt; decommissionedRS = new HashSet&lt;&gt;(admin.listDecommissionedRegionServers());<a name="line.455"></a>
+<span class="sourceLineNo">456</span>        if (CollectionUtils.isNotEmpty(decommissionedRS)) {<a name="line.456"></a>
+<span class="sourceLineNo">457</span>          regionServers.removeIf(decommissionedRS::contains);<a name="line.457"></a>
+<span class="sourceLineNo">458</span>          LOG.debug("Excluded RegionServers from unloading regions to because they "<a name="line.458"></a>
+<span class="sourceLineNo">459</span>            + "are marked as decommissioned. Servers: {}", decommissionedRS);<a name="line.459"></a>
+<span class="sourceLineNo">460</span>        }<a name="line.460"></a>
+<span class="sourceLineNo">461</span><a name="line.461"></a>
+<span class="sourceLineNo">462</span>        stripMaster(regionServers);<a name="line.462"></a>
+<span class="sourceLineNo">463</span>        if (regionServers.isEmpty()) {<a name="line.463"></a>
+<span class="sourceLineNo">464</span>          LOG.warn("No Regions were moved - no servers available");<a name="line.464"></a>
+<span class="sourceLineNo">465</span>          return false;<a name="line.465"></a>
+<span class="sourceLineNo">466</span>        } else {<a name="line.466"></a>
+<span class="sourceLineNo">467</span>          LOG.info("Available servers {}", regionServers);<a name="line.467"></a>
+<span class="sourceLineNo">468</span>        }<a name="line.468"></a>
+<span class="sourceLineNo">469</span>        unloadRegions(server, regionServers, movedRegions);<a name="line.469"></a>
+<span class="sourceLineNo">470</span>      } catch (Exception e) {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>        LOG.error("Error while unloading regions ", e);<a name="line.471"></a>
+<span class="sourceLineNo">472</span>        return false;<a name="line.472"></a>
+<span class="sourceLineNo">473</span>      } finally {<a name="line.473"></a>
+<span class="sourceLineNo">474</span>        if (movedRegions != null) {<a name="line.474"></a>
+<span class="sourceLineNo">475</span>          writeFile(filename, movedRegions);<a name="line.475"></a>
+<span class="sourceLineNo">476</span>        }<a name="line.476"></a>
+<span class="sourceLineNo">477</span>      }<a name="line.477"></a>
+<span class="sourceLineNo">478</span>      return true;<a name="line.478"></a>
+<span class="sourceLineNo">479</span>    });<a name="line.479"></a>
+<span class="sourceLineNo">480</span>    return waitTaskToFinish(unloadPool, unloadTask, "unloading");<a name="line.480"></a>
+<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
+<span class="sourceLineNo">482</span><a name="line.482"></a>
+<span class="sourceLineNo">483</span>  @InterfaceAudience.Private<a name="line.483"></a>
+<span class="sourceLineNo">484</span>  Collection&lt;ServerName&gt; filterRSGroupServers(RSGroupInfo rsgroup,<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    Collection&lt;ServerName&gt; onlineServers) {<a name="line.485"></a>
+<span class="sourceLineNo">486</span>    if (rsgroup.getName().equals(RSGroupInfo.DEFAULT_GROUP)) {<a name="line.486"></a>
+<span class="sourceLineNo">487</span>      return onlineServers;<a name="line.487"></a>
+<span class="sourceLineNo">488</span>    }<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    List&lt;ServerName&gt; serverLists = new ArrayList&lt;&gt;(rsgroup.getServers().size());<a name="line.489"></a>
+<span class="sourceLineNo">490</span>    for (ServerName server : onlineServers) {<a name="line.490"></a>
+<span class="sourceLineNo">491</span>      Address address = Address.fromParts(server.getHostname(), server.getPort());<a name="line.491"></a>
+<span class="sourceLineNo">492</span>      if (rsgroup.containsServer(address)) {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>        serverLists.add(server);<a name="line.493"></a>
 <span class="sourceLineNo">494</span>      }<a name="line.494"></a>
-<span class="sourceLineNo">495</span>      LOG.info("Moving {} regions from {} to {} servers using {} threads .Ack Mode: {}",<a name="line.495"></a>
-<span class="sourceLineNo">496</span>        regionsToMove.size(), this.hostname, regionServers.size(), this.maxthreads, ack);<a name="line.496"></a>
-<span class="sourceLineNo">497</span><a name="line.497"></a>
-<span class="sourceLineNo">498</span>      Optional&lt;RegionInfo&gt; metaRegion = getMetaRegionInfoIfToBeMoved(regionsToMove);<a name="line.498"></a>
-<span class="sourceLineNo">499</span>      if (metaRegion.isPresent()) {<a name="line.499"></a>
-<span class="sourceLineNo">500</span>        RegionInfo meta = metaRegion.get();<a name="line.500"></a>
-<span class="sourceLineNo">501</span>        submitRegionMovesWhileUnloading(server, regionServers, movedRegions,<a name="line.501"></a>
-<span class="sourceLineNo">502</span>          Collections.singletonList(meta));<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        regionsToMove.remove(meta);<a name="line.503"></a>
-<span class="sourceLineNo">504</span>      }<a name="line.504"></a>
-<span class="sourceLineNo">505</span>      submitRegionMovesWhileUnloading(server, regionServers, movedRegions, regionsToMove);<a name="line.505"></a>
-<span class="sourceLineNo">506</span>    }<a name="line.506"></a>
-<span class="sourceLineNo">507</span>  }<a name="line.507"></a>
-<span class="sourceLineNo">508</span><a name="line.508"></a>
-<span class="sourceLineNo">509</span>  private void submitRegionMovesWhileUnloading(ServerName server, List&lt;ServerName&gt; regionServers,<a name="line.509"></a>
-<span class="sourceLineNo">510</span>    List&lt;RegionInfo&gt; movedRegions, List&lt;RegionInfo&gt; regionsToMove) throws Exception {<a name="line.510"></a>
-<span class="sourceLineNo">511</span>    final ExecutorService moveRegionsPool = Executors.newFixedThreadPool(this.maxthreads);<a name="line.511"></a>
-<span class="sourceLineNo">512</span>    List&lt;Future&lt;Boolean&gt;&gt; taskList = new ArrayList&lt;&gt;();<a name="line.512"></a>
-<span class="sourceLineNo">513</span>    int serverIndex = 0;<a name="line.513"></a>
-<span class="sourceLineNo">514</span>    for (RegionInfo regionToMove : regionsToMove) {<a name="line.514"></a>
-<span class="sourceLineNo">515</span>      if (ack) {<a name="line.515"></a>
-<span class="sourceLineNo">516</span>        Future&lt;Boolean&gt; task = moveRegionsPool.submit(new MoveWithAck(conn, regionToMove, server,<a name="line.516"></a>
-<span class="sourceLineNo">517</span>          regionServers.get(serverIndex), movedRegions));<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        taskList.add(task);<a name="line.518"></a>
-<span class="sourceLineNo">519</span>      } else {<a name="line.519"></a>
-<span class="sourceLineNo">520</span>        Future&lt;Boolean&gt; task = moveRegionsPool.submit(new MoveWithoutAck(admin, regionToMove,<a name="line.520"></a>
-<span class="sourceLineNo">521</span>          server, regionServers.get(serverIndex), movedRegions));<a name="line.521"></a>
-<span class="sourceLineNo">522</span>        taskList.add(task);<a name="line.522"></a>
-<span class="sourceLineNo">523</span>      }<a name="line.523"></a>
-<span class="sourceLineNo">524</span>      serverIndex = (serverIndex + 1) % regionServers.size();<a name="line.524"></a>
-<span class="sourceLineNo">525</span>    }<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    moveRegionsPool.shutdown();<a name="line.526"></a>
-<span class="sourceLineNo">527</span>    long timeoutInSeconds = regionsToMove.size()<a name="line.527"></a>
-<span class="sourceLineNo">528</span>      * admin.getConfiguration().getLong(MOVE_WAIT_MAX_KEY, DEFAULT_MOVE_WAIT_MAX);<a name="line.528"></a>
-<span class="sourceLineNo">529</span>    waitMoveTasksToFinish(moveRegionsPool, taskList, timeoutInSeconds);<a name="line.529"></a>
-<span class="sourceLineNo">530</span>  }<a name="line.530"></a>
-<span class="sourceLineNo">531</span><a name="line.531"></a>
-<span class="sourceLineNo">532</span>  private boolean waitTaskToFinish(ExecutorService pool, Future&lt;Boolean&gt; task, String operation)<a name="line.532"></a>
-<span class="sourceLineNo">533</span>    throws TimeoutException, InterruptedException, ExecutionException {<a name="line.533"></a>
-<span class="sourceLineNo">534</span>    pool.shutdown();<a name="line.534"></a>
-<span class="sourceLineNo">535</span>    try {<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      if (!pool.awaitTermination((long) this.timeout, TimeUnit.SECONDS)) {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>        LOG.warn("Timed out before finishing the " + operation + " operation. Timeout: "<a name="line.537"></a>
-<span class="sourceLineNo">538</span>          + this.timeout + "sec");<a name="line.538"></a>
-<span class="sourceLineNo">539</span>        pool.shutdownNow();<a name="line.539"></a>
-<span class="sourceLineNo">540</span>      }<a name="line.540"></a>
-<span class="sourceLineNo">541</span>    } catch (InterruptedException e) {<a name="line.541"></a>
-<span class="sourceLineNo">542</span>      pool.shutdownNow();<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      Thread.currentThread().interrupt();<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
-<span class="sourceLineNo">545</span>    try {<a name="line.545"></a>
-<span class="sourceLineNo">546</span>      return task.get(5, TimeUnit.SECONDS);<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    } catch (InterruptedException e) {<a name="line.547"></a>
-<span class="sourceLineNo">548</span>      LOG.warn("Interrupted while " + operation + " Regions on " + this.hostname, e);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>      throw e;<a name="line.549"></a>
-<span class="sourceLineNo">550</span>    } catch (ExecutionException e) {<a name="line.550"></a>
-<span class="sourceLineNo">551</span>      LOG.error("Error while " + operation + " regions on RegionServer " + this.hostname, e);<a name="line.551"></a>
-<span class="sourceLineNo">552</span>      throw e;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>    }<a name="line.553"></a>
-<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
-<span class="sourceLineNo">555</span><a name="line.555"></a>
-<span class="sourceLineNo">556</span>  private void waitMoveTasksToFinish(ExecutorService moveRegionsPool,<a name="line.556"></a>
-<span class="sourceLineNo">557</span>    List&lt;Future&lt;Boolean&gt;&gt; taskList, long timeoutInSeconds) throws Exception {<a name="line.557"></a>
+<span class="sourceLineNo">495</span>    }<a name="line.495"></a>
+<span class="sourceLineNo">496</span>    return serverLists;<a name="line.496"></a>
+<span class="sourceLineNo">497</span>  }<a name="line.497"></a>
+<span class="sourceLineNo">498</span><a name="line.498"></a>
+<span class="sourceLineNo">499</span>  private void unloadRegions(ServerName server, List&lt;ServerName&gt; regionServers,<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    List&lt;RegionInfo&gt; movedRegions) throws Exception {<a name="line.500"></a>
+<span class="sourceLineNo">501</span>    while (true) {<a name="line.501"></a>
+<span class="sourceLineNo">502</span>      List&lt;RegionInfo&gt; regionsToMove = admin.getRegions(server);<a name="line.502"></a>
+<span class="sourceLineNo">503</span>      regionsToMove.removeAll(movedRegions);<a name="line.503"></a>
+<span class="sourceLineNo">504</span>      if (regionsToMove.isEmpty()) {<a name="line.504"></a>
+<span class="sourceLineNo">505</span>        LOG.info("No Regions to move....Quitting now");<a name="line.505"></a>
+<span class="sourceLineNo">506</span>        break;<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      }<a name="line.507"></a>
+<span class="sourceLineNo">508</span>      LOG.info("Moving {} regions from {} to {} servers using {} threads .Ack Mode: {}",<a name="line.508"></a>
+<span class="sourceLineNo">509</span>        regionsToMove.size(), this.hostname, regionServers.size(), this.maxthreads, ack);<a name="line.509"></a>
+<span class="sourceLineNo">510</span><a name="line.510"></a>
+<span class="sourceLineNo">511</span>      Optional&lt;RegionInfo&gt; metaRegion = getMetaRegionInfoIfToBeMoved(regionsToMove);<a name="line.511"></a>
+<span class="sourceLineNo">512</span>      if (metaRegion.isPresent()) {<a name="line.512"></a>
+<span class="sourceLineNo">513</span>        RegionInfo meta = metaRegion.get();<a name="line.513"></a>
+<span class="sourceLineNo">514</span>        submitRegionMovesWhileUnloading(server, regionServers, movedRegions,<a name="line.514"></a>
+<span class="sourceLineNo">515</span>          Collections.singletonList(meta));<a name="line.515"></a>
+<span class="sourceLineNo">516</span>        regionsToMove.remove(meta);<a name="line.516"></a>
+<span class="sourceLineNo">517</span>      }<a name="line.517"></a>
+<span class="sourceLineNo">518</span>      submitRegionMovesWhileUnloading(server, regionServers, movedRegions, regionsToMove);<a name="line.518"></a>
+<span class="sourceLineNo">519</span>    }<a name="line.519"></a>
+<span class="sourceLineNo">520</span>  }<a name="line.520"></a>
+<span class="sourceLineNo">521</span><a name="line.521"></a>
+<span class="sourceLineNo">522</span>  private void submitRegionMovesWhileUnloading(ServerName server, List&lt;ServerName&gt; regionServers,<a name="line.522"></a>
+<span class="sourceLineNo">523</span>    List&lt;RegionInfo&gt; movedRegions, List&lt;RegionInfo&gt; regionsToMove) throws Exception {<a name="line.523"></a>
+<span class="sourceLineNo">524</span>    final ExecutorService moveRegionsPool = Executors.newFixedThreadPool(this.maxthreads);<a name="line.524"></a>
+<span class="sourceLineNo">525</span>    List&lt;Future&lt;Boolean&gt;&gt; taskList = new ArrayList&lt;&gt;();<a name="line.525"></a>
+<span class="sourceLineNo">526</span>    int serverIndex = 0;<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    for (RegionInfo regionToMove : regionsToMove) {<a name="line.527"></a>
+<span class="sourceLineNo">528</span>      if (ack) {<a name="line.528"></a>
+<span class="sourceLineNo">529</span>        Future&lt;Boolean&gt; task = moveRegionsPool.submit(new MoveWithAck(conn, regionToMove, server,<a name="line.529"></a>
+<span class="sourceLineNo">530</span>          regionServers.get(serverIndex), movedRegions));<a name="line.530"></a>
+<span class="sourceLineNo">531</span>        taskList.add(task);<a name="line.531"></a>
+<span class="sourceLineNo">532</span>      } else {<a name="line.532"></a>
+<span class="sourceLineNo">533</span>        Future&lt;Boolean&gt; task = moveRegionsPool.submit(new MoveWithoutAck(admin, regionToMove,<a name="line.533"></a>
+<span class="sourceLineNo">534</span>          server, regionServers.get(serverIndex), movedRegions));<a name="line.534"></a>
+<span class="sourceLineNo">535</span>        taskList.add(task);<a name="line.535"></a>
+<span class="sourceLineNo">536</span>      }<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      serverIndex = (serverIndex + 1) % regionServers.size();<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    }<a name="line.538"></a>
+<span class="sourceLineNo">539</span>    moveRegionsPool.shutdown();<a name="line.539"></a>
+<span class="sourceLineNo">540</span>    long timeoutInSeconds = regionsToMove.size()<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      * admin.getConfiguration().getLong(MOVE_WAIT_MAX_KEY, DEFAULT_MOVE_WAIT_MAX);<a name="line.541"></a>
+<span class="sourceLineNo">542</span>    waitMoveTasksToFinish(moveRegionsPool, taskList, timeoutInSeconds);<a name="line.542"></a>
+<span class="sourceLineNo">543</span>  }<a name="line.543"></a>
+<span class="sourceLineNo">544</span><a name="line.544"></a>
+<span class="sourceLineNo">545</span>  private boolean waitTaskToFinish(ExecutorService pool, Future&lt;Boolean&gt; task, String operation)<a name="line.545"></a>
+<span class="sourceLineNo">546</span>    throws TimeoutException, InterruptedException, ExecutionException {<a name="line.546"></a>
+<span class="sourceLineNo">547</span>    pool.shutdown();<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    try {<a name="line.548"></a>
+<span class="sourceLineNo">549</span>      if (!pool.awaitTermination((long) this.timeout, TimeUnit.SECONDS)) {<a name="line.549"></a>
+<span class="sourceLineNo">550</span>        LOG.warn("Timed out before finishing the " + operation + " operation. Timeout: "<a name="line.550"></a>
+<span class="sourceLineNo">551</span>          + this.timeout + "sec");<a name="line.551"></a>
+<span class="sourceLineNo">552</span>        pool.shutdownNow();<a name="line.552"></a>
+<span class="sourceLineNo">553</span>      }<a name="line.553"></a>
+<span class="sourceLineNo">554</span>    } catch (InterruptedException e) {<a name="line.554"></a>
+<span class="sourceLineNo">555</span>      pool.shutdownNow();<a name="line.555"></a>
+<span class="sourceLineNo">556</span>      Thread.currentThread().interrupt();<a name="line.556"></a>
+<span class="sourceLineNo">557</span>    }<a name="line.557"></a>
 <span class="sourceLineNo">558</span>    try {<a name="line.558"></a>
-<span class="sourceLineNo">559</span>      if (!moveRegionsPool.awaitTermination(timeoutInSeconds, TimeUnit.SECONDS)) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>        moveRegionsPool.shutdownNow();<a name="line.560"></a>
-<span class="sourceLineNo">561</span>      }<a name="line.561"></a>
-<span class="sourceLineNo">562</span>    } catch (InterruptedException e) {<a name="line.562"></a>
-<span class="sourceLineNo">563</span>      moveRegionsPool.shutdownNow();<a name="line.563"></a>
-<span class="sourceLineNo">564</span>      Thread.currentThread().interrupt();<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    }<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    for (Future&lt;Boolean&gt; future : taskList) {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>      try {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>        // if even after shutdownNow threads are stuck we wait for 5 secs max<a name="line.568"></a>
-<span class="sourceLineNo">569</span>        if (!future.get(5, TimeUnit.SECONDS)) {<a name="line.569"></a>
-<span class="sourceLineNo">570</span>          LOG.error("Was Not able to move region....Exiting Now");<a name="line.570"></a>
-<span class="sourceLineNo">571</span>          throw new Exception("Could not move region Exception");<a name="line.571"></a>
-<span class="sourceLineNo">572</span>        }<a name="line.572"></a>
-<span class="sourceLineNo">573</span>      } catch (InterruptedException e) {<a name="line.573"></a>
-<span class="sourceLineNo">574</span>        LOG.error("Interrupted while waiting for Thread to Complete " + e.getMessage(), e);<a name="line.574"></a>
-<span class="sourceLineNo">575</span>        throw e;<a name="line.575"></a>
-<span class="sourceLineNo">576</span>      } catch (ExecutionException e) {<a name="line.576"></a>
-<span class="sourceLineNo">577</span>        boolean ignoreFailure = ignoreRegionMoveFailure(e);<a name="line.577"></a>
-<span class="sourceLineNo">578</span>        if (ignoreFailure) {<a name="line.578"></a>
-<span class="sourceLineNo">579</span>          LOG.debug("Ignore region move failure, it might have been split/merged.", e);<a name="line.579"></a>
-<span class="sourceLineNo">580</span>        } else {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>          LOG.error("Got Exception From Thread While moving region {}", e.getMessage(), e);<a name="line.581"></a>
-<span class="sourceLineNo">582</span>          throw e;<a name="line.582"></a>
-<span class="sourceLineNo">583</span>        }<a name="line.583"></a>
-<span class="sourceLineNo">584</span>      } catch (CancellationException e) {<a name="line.584"></a>
-<span class="sourceLineNo">585</span>        LOG.error("Thread for moving region cancelled. Timeout for cancellation:" + timeoutInSeconds<a name="line.585"></a>
-<span class="sourceLineNo">586</span>          + "secs", e);<a name="line.586"></a>
-<span class="sourceLineNo">587</span>        throw e;<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      }<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    }<a name="line.589"></a>
-<span class="sourceLineNo">590</span>  }<a name="line.590"></a>
-<span class="sourceLineNo">591</span><a name="line.591"></a>
-<span class="sourceLineNo">592</span>  private boolean ignoreRegionMoveFailure(ExecutionException e) {<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    boolean ignoreFailure = false;<a name="line.593"></a>
-<span class="sourceLineNo">594</span>    if (e.getCause() instanceof UnknownRegionException) {<a name="line.594"></a>
-<span class="sourceLineNo">595</span>      // region does not exist anymore<a name="line.595"></a>
-<span class="sourceLineNo">596</span>      ignoreFailure = true;<a name="line.596"></a>
-<span class="sourceLineNo">597</span>    } else if (<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      e.getCause() instanceof DoNotRetryRegionException &amp;&amp; e.getCause().getMessage() != null<a name="line.598"></a>
-<span class="sourceLineNo">599</span>        &amp;&amp; e.getCause().getMessage()<a name="line.599"></a>
-<span class="sourceLineNo">600</span>          .contains(AssignmentManager.UNEXPECTED_STATE_REGION + "state=SPLIT,")<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    ) {<a name="line.601"></a>
-<span class="sourceLineNo">602</span>      // region is recently split<a name="line.602"></a>
-<span class="sourceLineNo">603</span>      ignoreFailure = true;<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    }<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    return ignoreFailure;<a name="line.605"></a>
-<span class="sourceLineNo">606</span>  }<a name="line.606"></a>
-<span class="sourceLineNo">607</span><a name="line.607"></a>
-<span class="sourceLineNo">608</span>  private ServerName getTargetServer() throws Exception {<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    ServerName server = null;<a name="line.609"></a>
-<span class="sourceLineNo">610</span>    int maxWaitInSeconds =<a name="line.610"></a>
-<span class="sourceLineNo">611</span>      admin.getConfiguration().getInt(SERVERSTART_WAIT_MAX_KEY, DEFAULT_SERVERSTART_WAIT_MAX);<a name="line.611"></a>
-<span class="sourceLineNo">612</span>    long maxWait = EnvironmentEdgeManager.currentTime() + maxWaitInSeconds * 1000;<a name="line.612"></a>
-<span class="sourceLineNo">613</span>    while (EnvironmentEdgeManager.currentTime() &lt; maxWait) {<a name="line.613"></a>
-<span class="sourceLineNo">614</span>      try {<a name="line.614"></a>
-<span class="sourceLineNo">615</span>        List&lt;ServerName&gt; regionServers = new ArrayList&lt;&gt;();<a name="line.615"></a>
-<span class="sourceLineNo">616</span>        regionServers.addAll(admin.getRegionServers());<a name="line.616"></a>
-<span class="sourceLineNo">617</span>        // Remove the host Region server from target Region Servers list<a name="line.617"></a>
-<span class="sourceLineNo">618</span>        server = stripServer(regionServers, hostname, port);<a name="line.618"></a>
-<span class="sourceLineNo">619</span>        if (server != null) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>          break;<a name="line.620"></a>
-<span class="sourceLineNo">621</span>        } else {<a name="line.621"></a>
-<span class="sourceLineNo">622</span>          LOG.warn("Server " + hostname + ":" + port + " is not up yet, waiting");<a name="line.622"></a>
-<span class="sourceLineNo">623</span>        }<a name="line.623"></a>
-<span class="sourceLineNo">624</span>      } catch (IOException e) {<a name="line.624"></a>
-<span class="sourceLineNo">625</span>        LOG.warn("Could not get list of region servers", e);<a name="line.625"></a>
-<span class="sourceLineNo">626</span>      }<a name="line.626"></a>
-<span class="sourceLineNo">627</span>      Thread.sleep(500);<a name="line.627"></a>
-<span class="sourceLineNo">628</span>    }<a name="line.628"></a>
-<span class="sourceLineNo">629</span>    if (server == null) {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>      LOG.error("Server " + hostname + ":" + port + " is not up. Giving up.");<a name="line.630"></a>
-<span class="sourceLineNo">631</span>      throw new Exception("Server " + hostname + ":" + port + " to load regions not online");<a name="line.631"></a>
-<span class="sourceLineNo">632</span>    }<a name="line.632"></a>
-<span class="sourceLineNo">633</span>    return server;<a name="line.633"></a>
-<span class="sourceLineNo">634</span>  }<a name="line.634"></a>
-<span class="sourceLineNo">635</span><a name="line.635"></a>
-<span class="sourceLineNo">636</span>  private List&lt;RegionInfo&gt; readRegionsFromFile(String filename) throws IOException {<a name="line.636"></a>
-<span class="sourceLineNo">637</span>    List&lt;RegionInfo&gt; regions = new ArrayList&lt;&gt;();<a name="line.637"></a>
-<span class="sourceLineNo">638</span>    File f = new File(filename);<a name="line.638"></a>
-<span class="sourceLineNo">639</span>    if (!f.exists()) {<a name="line.639"></a>
-<span class="sourceLineNo">640</span>      return regions;<a name="line.640"></a>
+<span class="sourceLineNo">559</span>      return task.get(5, TimeUnit.SECONDS);<a name="line.559"></a>
+<span class="sourceLineNo">560</span>    } catch (InterruptedException e) {<a name="line.560"></a>
+<span class="sourceLineNo">561</span>      LOG.warn("Interrupted while " + operation + " Regions on " + this.hostname, e);<a name="line.561"></a>
+<span class="sourceLineNo">562</span>      throw e;<a name="line.562"></a>
+<span class="sourceLineNo">563</span>    } catch (ExecutionException e) {<a name="line.563"></a>
+<span class="sourceLineNo">564</span>      LOG.error("Error while " + operation + " regions on RegionServer " + this.hostname, e);<a name="line.564"></a>
+<span class="sourceLineNo">565</span>      throw e;<a name="line.565"></a>
+<span class="sourceLineNo">566</span>    }<a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  private void waitMoveTasksToFinish(ExecutorService moveRegionsPool,<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    List&lt;Future&lt;Boolean&gt;&gt; taskList, long timeoutInSeconds) throws Exception {<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    try {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      if (!moveRegionsPool.awaitTermination(timeoutInSeconds, TimeUnit.SECONDS)) {<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        moveRegionsPool.shutdownNow();<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>    } catch (InterruptedException e) {<a name="line.575"></a>
+<span class="sourceLineNo">576</span>      moveRegionsPool.shutdownNow();<a name="line.576"></a>
+<span class="sourceLineNo">577</span>      Thread.currentThread().interrupt();<a name="line.577"></a>
+<span class="sourceLineNo">578</span>    }<a name="line.578"></a>
+<span class="sourceLineNo">579</span>    for (Future&lt;Boolean&gt; future : taskList) {<a name="line.579"></a>
+<span class="sourceLineNo">580</span>      try {<a name="line.580"></a>
+<span class="sourceLineNo">581</span>        // if even after shutdownNow threads are stuck we wait for 5 secs max<a name="line.581"></a>
+<span class="sourceLineNo">582</span>        if (!future.get(5, TimeUnit.SECONDS)) {<a name="line.582"></a>
+<span class="sourceLineNo">583</span>          LOG.error("Was Not able to move region....Exiting Now");<a name="line.583"></a>
+<span class="sourceLineNo">584</span>          throw new Exception("Could not move region Exception");<a name="line.584"></a>
+<span class="sourceLineNo">585</span>        }<a name="line.585"></a>
+<span class="sourceLineNo">586</span>      } catch (InterruptedException e) {<a name="line.586"></a>
+<span class="sourceLineNo">587</span>        LOG.error("Interrupted while waiting for Thread to Complete " + e.getMessage(), e);<a name="line.587"></a>
+<span class="sourceLineNo">588</span>        throw e;<a name="line.588"></a>
+<span class="sourceLineNo">589</span>      } catch (ExecutionException e) {<a name="line.589"></a>
+<span class="sourceLineNo">590</span>        boolean ignoreFailure = ignoreRegionMoveFailure(e);<a name="line.590"></a>
+<span class="sourceLineNo">591</span>        if (ignoreFailure) {<a name="line.591"></a>
+<span class="sourceLineNo">592</span>          LOG.debug("Ignore region move failure, it might have been split/merged.", e);<a name="line.592"></a>
+<span class="sourceLineNo">593</span>        } else {<a name="line.593"></a>
+<span class="sourceLineNo">594</span>          LOG.error("Got Exception From Thread While moving region {}", e.getMessage(), e);<a name="line.594"></a>
+<span class="sourceLineNo">595</span>          throw e;<a name="line.595"></a>
+<span class="sourceLineNo">596</span>        }<a name="line.596"></a>
+<span class="sourceLineNo">597</span>      } catch (CancellationException e) {<a name="line.597"></a>
+<span class="sourceLineNo">598</span>        LOG.error("Thread for moving region cancelled. Timeout for cancellation:" + timeoutInSeconds<a name="line.598"></a>
+<span class="sourceLineNo">599</span>          + "secs", e);<a name="line.599"></a>
+<span class="sourceLineNo">600</span>        throw e;<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      }<a name="line.601"></a>
+<span class="sourceLineNo">602</span>    }<a name="line.602"></a>
+<span class="sourceLineNo">603</span>  }<a name="line.603"></a>
+<span class="sourceLineNo">604</span><a name="line.604"></a>
+<span class="sourceLineNo">605</span>  private boolean ignoreRegionMoveFailure(ExecutionException e) {<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    boolean ignoreFailure = false;<a name="line.606"></a>
+<span class="sourceLineNo">607</span>    if (e.getCause() instanceof UnknownRegionException) {<a name="line.607"></a>
+<span class="sourceLineNo">608</span>      // region does not exist anymore<a name="line.608"></a>
+<span class="sourceLineNo">609</span>      ignoreFailure = true;<a name="line.609"></a>
+<span class="sourceLineNo">610</span>    } else if (<a name="line.610"></a>
+<span class="sourceLineNo">611</span>      e.getCause() instanceof DoNotRetryRegionException &amp;&amp; e.getCause().getMessage() != null<a name="line.611"></a>
+<span class="sourceLineNo">612</span>        &amp;&amp; e.getCause().getMessage()<a name="line.612"></a>
+<span class="sourceLineNo">613</span>          .contains(AssignmentManager.UNEXPECTED_STATE_REGION + "state=SPLIT,")<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    ) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>      // region is recently split<a name="line.615"></a>
+<span class="sourceLineNo">616</span>      ignoreFailure = true;<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    }<a name="line.617"></a>
+<span class="sourceLineNo">618</span>    return ignoreFailure;<a name="line.618"></a>
+<span class="sourceLineNo">619</span>  }<a name="line.619"></a>
+<span class="sourceLineNo">620</span><a name="line.620"></a>
+<span class="sourceLineNo">621</span>  private ServerName getTargetServer() throws Exception {<a name="line.621"></a>
+<span class="sourceLineNo">622</span>    ServerName server = null;<a name="line.622"></a>
+<span class="sourceLineNo">623</span>    int maxWaitInSeconds =<a name="line.623"></a>
+<span class="sourceLineNo">624</span>      admin.getConfiguration().getInt(SERVERSTART_WAIT_MAX_KEY, DEFAULT_SERVERSTART_WAIT_MAX);<a name="line.624"></a>
+<span class="sourceLineNo">625</span>    long maxWait = EnvironmentEdgeManager.currentTime() + maxWaitInSeconds * 1000;<a name="line.625"></a>
+<span class="sourceLineNo">626</span>    while (EnvironmentEdgeManager.currentTime() &lt; maxWait) {<a name="line.626"></a>
+<span class="sourceLineNo">627</span>      try {<a name="line.627"></a>
+<span class="sourceLineNo">628</span>        List&lt;ServerName&gt; regionServers = new ArrayList&lt;&gt;();<a name="line.628"></a>
+<span class="sourceLineNo">629</span>        regionServers.addAll(admin.getRegionServers());<a name="line.629"></a>
+<span class="sourceLineNo">630</span>        // Remove the host Region server from target Region Servers list<a name="line.630"></a>
+<span class="sourceLineNo">631</span>        server = stripServer(regionServers, hostname, port);<a name="line.631"></a>
+<span class="sourceLineNo">632</span>        if (server != null) {<a name="line.632"></a>
+<span class="sourceLineNo">633</span>          break;<a name="line.633"></a>
+<span class="sourceLineNo">634</span>        } else {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>          LOG.warn("Server " + hostname + ":" + port + " is not up yet, waiting");<a name="line.635"></a>
+<span class="sourceLineNo">636</span>        }<a name="line.636"></a>
+<span class="sourceLineNo">637</span>      } catch (IOException e) {<a name="line.637"></a>
+<span class="sourceLineNo">638</span>        LOG.warn("Could not get list of region servers", e);<a name="line.638"></a>
+<span class="sourceLineNo">639</span>      }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>      Thread.sleep(500);<a name="line.640"></a>
 <span class="sourceLineNo">641</span>    }<a name="line.641"></a>
-<span class="sourceLineNo">642</span>    try (<a name="line.642"></a>
-<span class="sourceLineNo">643</span>      DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(f)))) {<a name="line.643"></a>
-<span class="sourceLineNo">644</span>      int numRegions = dis.readInt();<a name="line.644"></a>
-<span class="sourceLineNo">645</span>      int index = 0;<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      while (index &lt; numRegions) {<a name="line.646"></a>
-<span class="sourceLineNo">647</span>        regions.add(RegionInfo.parseFromOrNull(Bytes.readByteArray(dis)));<a name="line.647"></a>
-<span class="sourceLineNo">648</span>        index++;<a name="line.648"></a>
-<span class="sourceLineNo">649</span>      }<a name="line.649"></a>
-<span class="sourceLineNo">650</span>    } catch (IOException e) {<a name="line.650"></a>
-<span class="sourceLineNo">651</span>      LOG.error("Error while reading regions from file:" + filename, e);<a name="line.651"></a>
-<span class="sourceLineNo">652</span>      throw e;<a name="line.652"></a>
-<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
-<span class="sourceLineNo">654</span>    return regions;<a name="line.654"></a>
-<span class="sourceLineNo">655</span>  }<a name="line.655"></a>
-<span class="sourceLineNo">656</span><a name="line.656"></a>
-<span class="sourceLineNo">657</span>  /**<a name="line.657"></a>
-<span class="sourceLineNo">658</span>   * Write the number of regions moved in the first line followed by regions moved in subsequent<a name="line.658"></a>
-<span class="sourceLineNo">659</span>   * lines<a name="line.659"></a>
-<span class="sourceLineNo">660</span>   */<a name="line.660"></a>
-<span class="sourceLineNo">661</span>  private void writeFile(String filename, List&lt;RegionInfo&gt; movedRegions) throws IOException {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>    try (DataOutputStream dos =<a name="line.662"></a>
-<span class="sourceLineNo">663</span>      new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)))) {<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      dos.writeInt(movedRegions.size());<a name="line.664"></a>
-<span class="sourceLineNo">665</span>      for (RegionInfo region : movedRegions) {<a name="line.665"></a>
-<span class="sourceLineNo">666</span>        Bytes.writeByteArray(dos, RegionInfo.toByteArray(region));<a name="line.666"></a>
-<span class="sourceLineNo">667</span>      }<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    } catch (IOException e) {<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      LOG.error("ERROR: Was Not able to write regions moved to output file but moved "<a name="line.669"></a>
-<span class="sourceLineNo">670</span>        + movedRegions.size() + " regions", e);<a name="line.670"></a>
-<span class="sourceLineNo">671</span>      throw e;<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    }<a name="line.672"></a>
-<span class="sourceLineNo">673</span>  }<a name="line.673"></a>
-<span class="sourceLineNo">674</span><a name="line.674"></a>
-<span class="sourceLineNo">675</span>  private void deleteFile(String filename) {<a name="line.675"></a>
-<span class="sourceLineNo">676</span>    File f = new File(filename);<a name="line.676"></a>
-<span class="sourceLineNo">677</span>    if (f.exists()) {<a name="line.677"></a>
-<span class="sourceLineNo">678</span>      f.delete();<a name="line.678"></a>
-<span class="sourceLineNo">679</span>    }<a name="line.679"></a>
-<span class="sourceLineNo">680</span>  }<a name="line.680"></a>
-<span class="sourceLineNo">681</span><a name="line.681"></a>
-<span class="sourceLineNo">682</span>  /**<a name="line.682"></a>
-<span class="sourceLineNo">683</span>   * @param filename The file should have 'host:port' per line<a name="line.683"></a>
-<span class="sourceLineNo">684</span>   * @return List of servers from the file in format 'hostname:port'.<a name="line.684"></a>
-<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
-<span class="sourceLineNo">686</span>  private List&lt;String&gt; readServersFromFile(String filename) throws IOException {<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    List&lt;String&gt; servers = new ArrayList&lt;&gt;();<a name="line.687"></a>
-<span class="sourceLineNo">688</span>    if (filename != null) {<a name="line.688"></a>
-<span class="sourceLineNo">689</span>      try {<a name="line.689"></a>
-<span class="sourceLineNo">690</span>        Files.readAllLines(Paths.get(filename)).stream().map(String::trim)<a name="line.690"></a>
-<span class="sourceLineNo">691</span>          .filter(((Predicate&lt;String&gt;) String::isEmpty).negate()).map(String::toLowerCase)<a name="line.691"></a>
-<span class="sourceLineNo">692</span>          .forEach(servers::add);<a name="line.692"></a>
-<span class="sourceLineNo">693</span>      } catch (IOException e) {<a name="line.693"></a>
-<span class="sourceLineNo">694</span>        LOG.error("Exception while reading servers from file,", e);<a name="line.694"></a>
-<span class="sourceLineNo">695</span>        throw e;<a name="line.695"></a>
-<span class="sourceLineNo">696</span>      }<a name="line.696"></a>
-<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
-<span class="sourceLineNo">698</span>    return servers;<a name="line.698"></a>
-<span class="sourceLineNo">699</span>  }<a name="line.699"></a>
-<span class="sourceLineNo">700</span><a name="line.700"></a>
-<span class="sourceLineNo">701</span>  /**<a name="line.701"></a>
-<span class="sourceLineNo">702</span>   * Designates or excludes the servername whose hostname and port portion matches the list given in<a name="line.702"></a>
-<span class="sourceLineNo">703</span>   * the file. Example:&lt;br&gt;<a name="line.703"></a>
-<span class="sourceLineNo">704</span>   * If you want to designated RSs, suppose designatedFile has RS1, regionServers has RS1, RS2 and<a name="line.704"></a>
-<span class="sourceLineNo">705</span>   * RS3. When we call includeExcludeRegionServers(designatedFile, regionServers, true), RS2 and RS3<a name="line.705"></a>
-<span class="sourceLineNo">706</span>   * are removed from regionServers list so that regions can move to only RS1. If you want to<a name="line.706"></a>
-<span class="sourceLineNo">707</span>   * exclude RSs, suppose excludeFile has RS1, regionServers has RS1, RS2 and RS3. When we call<a name="line.707"></a>
-<span class="sourceLineNo">708</span>   * includeExcludeRegionServers(excludeFile, servers, false), RS1 is removed from regionServers<a name="line.708"></a>
-<span class="sourceLineNo">709</span>   * list so that regions can move to only RS2 and RS3.<a name="line.709"></a>
-<span class="sourceLineNo">710</span>   */<a name="line.710"></a>
-<span class="sourceLineNo">711</span>  private void includeExcludeRegionServers(String fileName, List&lt;ServerName&gt; regionServers,<a name="line.711"></a>
-<span class="sourceLineNo">712</span>    boolean isInclude) throws IOException {<a name="line.712"></a>
-<span class="sourceLineNo">713</span>    if (fileName != null) {<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      List&lt;String&gt; servers = readServersFromFile(fileName);<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      if (servers.isEmpty()) {<a name="line.715"></a>
-<span class="sourceLineNo">716</span>        LOG.warn("No servers provided in the file: {}." + fileName);<a name="line.716"></a>
-<span class="sourceLineNo">717</span>        return;<a name="line.717"></a>
-<span class="sourceLineNo">718</span>      }<a name="line.718"></a>
-<span class="sourceLineNo">719</span>      Iterator&lt;ServerName&gt; i = regionServers.iterator();<a name="line.719"></a>
-<span class="sourceLineNo">720</span>      while (i.hasNext()) {<a name="line.720"></a>
-<span class="sourceLineNo">721</span>        String rs = i.next().getServerName();<a name="line.721"></a>
-<span class="sourceLineNo">722</span>        String rsPort = rs.split(ServerName.SERVERNAME_SEPARATOR)[0].toLowerCase() + ":"<a name="line.722"></a>
-<span class="sourceLineNo">723</span>          + rs.split(ServerName.SERVERNAME_SEPARATOR)[1];<a name="line.723"></a>
-<span class="sourceLineNo">724</span>        if (isInclude != servers.contains(rsPort)) {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>          i.remove();<a name="line.725"></a>
-<span class="sourceLineNo">726</span>        }<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      }<a name="line.727"></a>
-<span class="sourceLineNo">728</span>    }<a name="line.728"></a>
-<span class="sourceLineNo">729</span>  }<a name="line.729"></a>
-<span class="sourceLineNo">730</span><a name="line.730"></a>
-<span class="sourceLineNo">731</span>  /**<a name="line.731"></a>
-<span class="sourceLineNo">732</span>   * Exclude master from list of RSs to move regions to<a name="line.732"></a>
-<span class="sourceLineNo">733</span>   */<a name="line.733"></a>
-<span class="sourceLineNo">734</span>  private void stripMaster(List&lt;ServerName&gt; regionServers) throws IOException {<a name="line.734"></a>
-<span class="sourceLineNo">735</span>    ServerName master = admin.getClusterMetrics(EnumSet.of(Option.MASTER)).getMasterName();<a name="line.735"></a>
-<span class="sourceLineNo">736</span>    stripServer(regionServers, master.getHostname(), master.getPort());<a name="line.736"></a>
-<span class="sourceLineNo">737</span>  }<a name="line.737"></a>
-<span class="sourceLineNo">738</span><a name="line.738"></a>
-<span class="sourceLineNo">739</span>  /**<a name="line.739"></a>
-<span class="sourceLineNo">740</span>   * Remove the servername whose hostname and port portion matches from the passed array of servers.<a name="line.740"></a>
-<span class="sourceLineNo">741</span>   * Returns as side-effect the servername removed.<a name="line.741"></a>
-<span class="sourceLineNo">742</span>   * @return server removed from list of Region Servers<a name="line.742"></a>
-<span class="sourceLineNo">743</span>   */<a name="line.743"></a>
-<span class="sourceLineNo">744</span>  private ServerName stripServer(List&lt;ServerName&gt; regionServers, String hostname, int port) {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    for (Iterator&lt;ServerName&gt; iter = regionServers.iterator(); iter.hasNext();) {<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      ServerName server = iter.next();<a name="line.746"></a>
-<span class="sourceLineNo">747</span>      if (<a name="line.747"></a>
-<span class="sourceLineNo">748</span>        server.getAddress().getHostName().equalsIgnoreCase(hostname)<a name="line.748"></a>
-<span class="sourceLineNo">749</span>          &amp;&amp; server.getAddress().getPort() == port<a name="line.749"></a>
-<span class="sourceLineNo">750</span>      ) {<a name="line.750"></a>
-<span class="sourceLineNo">751</span>        iter.remove();<a name="line.751"></a>
-<span class="sourceLineNo">752</span>        return server;<a name="line.752"></a>
-<span class="sourceLineNo">753</span>      }<a name="line.753"></a>
-<span class="sourceLineNo">754</span>    }<a name="line.754"></a>
-<span class="sourceLineNo">755</span>    return null;<a name="line.755"></a>
-<span class="sourceLineNo">756</span>  }<a name="line.756"></a>
-<span class="sourceLineNo">757</span><a name="line.757"></a>
-<span class="sourceLineNo">758</span>  @Override<a name="line.758"></a>
-<span class="sourceLineNo">759</span>  protected void addOptions() {<a name="line.759"></a>
-<span class="sourceLineNo">760</span>    this.addRequiredOptWithArg("r", "regionserverhost", "region server &lt;hostname&gt;|&lt;hostname:port&gt;");<a name="line.760"></a>
-<span class="sourceLineNo">761</span>    this.addRequiredOptWithArg("o", "operation", "Expected: load/unload/unload_from_rack");<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    this.addOptWithArg("m", "maxthreads",<a name="line.762"></a>
-<span class="sourceLineNo">763</span>      "Define the maximum number of threads to use to unload and reload the regions");<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    this.addOptWithArg("x", "excludefile",<a name="line.764"></a>
-<span class="sourceLineNo">765</span>      "File with &lt;hostname:port&gt; per line to exclude as unload targets; default excludes only "<a name="line.765"></a>
-<span class="sourceLineNo">766</span>        + "target host; useful for rack decommisioning.");<a name="line.766"></a>
-<span class="sourceLineNo">767</span>    this.addOptWithArg("d", "designatedfile",<a name="line.767"></a>
-<span class="sourceLineNo">768</span>      "File with &lt;hostname:port&gt; per line as unload targets;" + "default is all online hosts");<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    this.addOptWithArg("f", "filename",<a name="line.769"></a>
-<span class="sourceLineNo">770</span>      "File to save regions list into unloading, or read from loading; "<a name="line.770"></a>
-<span class="sourceLineNo">771</span>        + "default /tmp/&lt;usernamehostname:port&gt;");<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    this.addOptNoArg("n", "noack",<a name="line.772"></a>
-<span class="sourceLineNo">773</span>      "Turn on No-Ack mode(default: false) which won't check if region is online on target "<a name="line.773"></a>
-<span class="sourceLineNo">774</span>        + "RegionServer, hence best effort. This is more performant in unloading and loading "<a name="line.774"></a>
-<span class="sourceLineNo">775</span>        + "but might lead to region being unavailable for some time till master reassigns it "<a name="line.775"></a>
-<span class="sourceLineNo">776</span>        + "in case the move failed");<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    this.addOptWithArg("t", "timeout", "timeout in seconds after which the tool will exit "<a name="line.777"></a>
-<span class="sourceLineNo">778</span>      + "irrespective of whether it finished or not;default Integer.MAX_VALUE");<a name="line.778"></a>
-<span class="sourceLineNo">779</span>  }<a name="line.779"></a>
-<span class="sourceLineNo">780</span><a name="line.780"></a>
-<span class="sourceLineNo">781</span>  @Override<a name="line.781"></a>
-<span class="sourceLineNo">782</span>  protected void processOptions(CommandLine cmd) {<a name="line.782"></a>
-<span class="sourceLineNo">783</span>    String hostname = cmd.getOptionValue("r");<a name="line.783"></a>
-<span class="sourceLineNo">784</span>    rmbuilder = new RegionMoverBuilder(hostname);<a name="line.784"></a>
-<span class="sourceLineNo">785</span>    if (cmd.hasOption('m')) {<a name="line.785"></a>
-<span class="sourceLineNo">786</span>      rmbuilder.maxthreads(Integer.parseInt(cmd.getOptionValue('m')));<a name="line.786"></a>
-<span class="sourceLineNo">787</span>    }<a name="line.787"></a>
-<span class="sourceLineNo">788</span>    if (cmd.hasOption('n')) {<a name="line.788"></a>
-<span class="sourceLineNo">789</span>      rmbuilder.ack(false);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>    }<a name="line.790"></a>
-<span class="sourceLineNo">791</span>    if (cmd.hasOption('f')) {<a name="line.791"></a>
-<span class="sourceLineNo">792</span>      rmbuilder.filename(cmd.getOptionValue('f'));<a name="line.792"></a>
-<span class="sourceLineNo">793</span>    }<a name="line.793"></a>
-<span class="sourceLineNo">794</span>    if (cmd.hasOption('x')) {<a name="line.794"></a>
-<span class="sourceLineNo">795</span>      rmbuilder.excludeFile(cmd.getOptionValue('x'));<a name="line.795"></a>
-<span class="sourceLineNo">796</span>    }<a name="line.796"></a>
-<span class="sourceLineNo">797</span>    if (cmd.hasOption('d')) {<a name="line.797"></a>
-<span class="sourceLineNo">798</span>      rmbuilder.designatedFile(cmd.getOptionValue('d'));<a name="line.798"></a>
-<span class="sourceLineNo">799</span>    }<a name="line.799"></a>
-<span class="sourceLineNo">800</span>    if (cmd.hasOption('t')) {<a name="line.800"></a>
-<span class="sourceLineNo">801</span>      rmbuilder.timeout(Integer.parseInt(cmd.getOptionValue('t')));<a name="line.801"></a>
-<span class="sourceLineNo">802</span>    }<a name="line.802"></a>
-<span class="sourceLineNo">803</span>    this.loadUnload = cmd.getOptionValue("o").toLowerCase(Locale.ROOT);<a name="line.803"></a>
-<span class="sourceLineNo">804</span>  }<a name="line.804"></a>
-<span class="sourceLineNo">805</span><a name="line.805"></a>
-<span class="sourceLineNo">806</span>  @Override<a name="line.806"></a>
-<span class="sourceLineNo">807</span>  protected int doWork() throws Exception {<a name="line.807"></a>
-<span class="sourceLineNo">808</span>    boolean success;<a name="line.808"></a>
-<span class="sourceLineNo">809</span>    try (RegionMover rm = rmbuilder.build()) {<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      if (loadUnload.equalsIgnoreCase("load")) {<a name="line.810"></a>
-<span class="sourceLineNo">811</span>        success = rm.load();<a name="line.811"></a>
-<span class="sourceLineNo">812</span>      } else if (loadUnload.equalsIgnoreCase("unload")) {<a name="line.812"></a>
-<span class="sourceLineNo">813</span>        success = rm.unload();<a name="line.813"></a>
-<span class="sourceLineNo">814</span>      } else if (loadUnload.equalsIgnoreCase("unload_from_rack")) {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>        success = rm.unloadFromRack();<a name="line.815"></a>
-<span class="sourceLineNo">816</span>      } else {<a name="line.816"></a>
-<span class="sourceLineNo">817</span>        printUsage();<a name="line.817"></a>
-<span class="sourceLineNo">818</span>        success = false;<a name="line.818"></a>
-<span class="sourceLineNo">819</span>      }<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    }<a name="line.820"></a>
-<span class="sourceLineNo">821</span>    return (success ? 0 : 1);<a name="line.821"></a>
-<span class="sourceLineNo">822</span>  }<a name="line.822"></a>
-<span class="sourceLineNo">823</span><a name="line.823"></a>
-<span class="sourceLineNo">824</span>  public static void main(String[] args) {<a name="line.824"></a>
-<span class="sourceLineNo">825</span>    try (RegionMover mover = new RegionMover()) {<a name="line.825"></a>
-<span class="sourceLineNo">826</span>      mover.doStaticMain(args);<a name="line.826"></a>
-<span class="sourceLineNo">827</span>    }<a name="line.827"></a>
-<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
-<span class="sourceLineNo">829</span>}<a name="line.829"></a>
+<span class="sourceLineNo">642</span>    if (server == null) {<a name="line.642"></a>
+<span class="sourceLineNo">643</span>      LOG.error("Server " + hostname + ":" + port + " is not up. Giving up.");<a name="line.643"></a>
+<span class="sourceLineNo">644</span>      throw new Exception("Server " + hostname + ":" + port + " to load regions not online");<a name="line.644"></a>
+<span class="sourceLineNo">645</span>    }<a name="line.645"></a>
+<span class="sourceLineNo">646</span>    return server;<a name="line.646"></a>
+<span class="sourceLineNo">647</span>  }<a name="line.647"></a>
+<span class="sourceLineNo">648</span><a name="line.648"></a>
+<span class="sourceLineNo">649</span>  private List&lt;RegionInfo&gt; readRegionsFromFile(String filename) throws IOException {<a name="line.649"></a>
+<span class="sourceLineNo">650</span>    List&lt;RegionInfo&gt; regions = new ArrayList&lt;&gt;();<a name="line.650"></a>
+<span class="sourceLineNo">651</span>    File f = new File(filename);<a name="line.651"></a>
+<span class="sourceLineNo">652</span>    if (!f.exists()) {<a name="line.652"></a>
+<span class="sourceLineNo">653</span>      return regions;<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    }<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    try (<a name="line.655"></a>
+<span class="sourceLineNo">656</span>      DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(f)))) {<a name="line.656"></a>
+<span class="sourceLineNo">657</span>      int numRegions = dis.readInt();<a name="line.657"></a>
+<span class="sourceLineNo">658</span>      int index = 0;<a name="line.658"></a>
+<span class="sourceLineNo">659</span>      while (index &lt; numRegions) {<a name="line.659"></a>
+<span class="sourceLineNo">660</span>        regions.add(RegionInfo.parseFromOrNull(Bytes.readByteArray(dis)));<a name="line.660"></a>
+<span class="sourceLineNo">661</span>        index++;<a name="line.661"></a>
+<span class="sourceLineNo">662</span>      }<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    } catch (IOException e) {<a name="line.663"></a>
+<span class="sourceLineNo">664</span>      LOG.error("Error while reading regions from file:" + filename, e);<a name="line.664"></a>
+<span class="sourceLineNo">665</span>      throw e;<a name="line.665"></a>
+<span class="sourceLineNo">666</span>    }<a name="line.666"></a>
+<span class="sourceLineNo">667</span>    return regions;<a name="line.667"></a>
+<span class="sourceLineNo">668</span>  }<a name="line.668"></a>
+<span class="sourceLineNo">669</span><a name="line.669"></a>
+<span class="sourceLineNo">670</span>  /**<a name="line.670"></a>
+<span class="sourceLineNo">671</span>   * Write the number of regions moved in the first line followed by regions moved in subsequent<a name="line.671"></a>
+<span class="sourceLineNo">672</span>   * lines<a name="line.672"></a>
+<span class="sourceLineNo">673</span>   */<a name="line.673"></a>
+<span class="sourceLineNo">674</span>  private void writeFile(String filename, List&lt;RegionInfo&gt; movedRegions) throws IOException {<a name="line.674"></a>
+<span class="sourceLineNo">675</span>    try (DataOutputStream dos =<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)))) {<a name="line.676"></a>
+<span class="sourceLineNo">677</span>      dos.writeInt(movedRegions.size());<a name="line.677"></a>
+<span class="sourceLineNo">678</span>      for (RegionInfo region : movedRegions) {<a name="line.678"></a>
+<span class="sourceLineNo">679</span>        Bytes.writeByteArray(dos, RegionInfo.toByteArray(region));<a name="line.679"></a>
+<span class="sourceLineNo">680</span>      }<a name="line.680"></a>
+<span class="sourceLineNo">681</span>    } catch (IOException e) {<a name="line.681"></a>
+<span class="sourceLineNo">682</span>      LOG.error("ERROR: Was Not able to write regions moved to output file but moved "<a name="line.682"></a>
+<span class="sourceLineNo">683</span>        + movedRegions.size() + " regions", e);<a name="line.683"></a>
+<span class="sourceLineNo">684</span>      throw e;<a name="line.684"></a>
+<span class="sourceLineNo">685</span>    }<a name="line.685"></a>
+<span class="sourceLineNo">686</span>  }<a name="line.686"></a>
+<span class="sourceLineNo">687</span><a name="line.687"></a>
+<span class="sourceLineNo">688</span>  private void deleteFile(String filename) {<a name="line.688"></a>
+<span class="sourceLineNo">689</span>    File f = new File(filename);<a name="line.689"></a>
+<span class="sourceLineNo">690</span>    if (f.exists()) {<a name="line.690"></a>
+<span class="sourceLineNo">691</span>      f.delete();<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    }<a name="line.692"></a>
+<span class="sourceLineNo">693</span>  }<a name="line.693"></a>
+<span class="sourceLineNo">694</span><a name="line.694"></a>
+<span class="sourceLineNo">695</span>  /**<a name="line.695"></a>
+<span class="sourceLineNo">696</span>   * @param filename The file should have 'host:port' per line<a name="line.696"></a>
+<span class="sourceLineNo">697</span>   * @return List of servers from the file in format 'hostname:port'.<a name="line.697"></a>
+<span class="sourceLineNo">698</span>   */<a name="line.698"></a>
+<span class="sourceLineNo">699</span>  private List&lt;String&gt; readServersFromFile(String filename) throws IOException {<a name="line.699"></a>
+<span class="sourceLineNo">700</span>    List&lt;String&gt; servers = new ArrayList&lt;&gt;();<a name="line.700"></a>
+<span class="sourceLineNo">701</span>    if (filename != null) {<a name="line.701"></a>
+<span class="sourceLineNo">702</span>      try {<a name="line.702"></a>
+<span class="sourceLineNo">703</span>        Files.readAllLines(Paths.get(filename)).stream().map(String::trim)<a name="line.703"></a>
+<span class="sourceLineNo">704</span>          .filter(((Predicate&lt;String&gt;) String::isEmpty).negate()).map(String::toLowerCase)<a name="line.704"></a>
+<span class="sourceLineNo">705</span>          .forEach(servers::add);<a name="line.705"></a>
+<span class="sourceLineNo">706</span>      } catch (IOException e) {<a name="line.706"></a>
+<span class="sourceLineNo">707</span>        LOG.error("Exception while reading servers from file,", e);<a name="line.707"></a>
+<span class="sourceLineNo">708</span>        throw e;<a name="line.708"></a>
+<span class="sourceLineNo">709</span>      }<a name="line.709"></a>
+<span class="sourceLineNo">710</span>    }<a name="line.710"></a>
+<span class="sourceLineNo">711</span>    return servers;<a name="line.711"></a>
+<span class="sourceLineNo">712</span>  }<a name="line.712"></a>
+<span class="sourceLineNo">713</span><a name="line.713"></a>
+<span class="sourceLineNo">714</span>  /**<a name="line.714"></a>
+<span class="sourceLineNo">715</span>   * Designates or excludes the servername whose hostname and port portion matches the list given in<a name="line.715"></a>
+<span class="sourceLineNo">716</span>   * the file. Example:&lt;br&gt;<a name="line.716"></a>
+<span class="sourceLineNo">717</span>   * If you want to designated RSs, suppose designatedFile has RS1, regionServers has RS1, RS2 and<a name="line.717"></a>
+<span class="sourceLineNo">718</span>   * RS3. When we call includeExcludeRegionServers(designatedFile, regionServers, true), RS2 and RS3<a name="line.718"></a>
+<span class="sourceLineNo">719</span>   * are removed from regionServers list so that regions can move to only RS1. If you want to<a name="line.719"></a>
+<span class="sourceLineNo">720</span>   * exclude RSs, suppose excludeFile has RS1, regionServers has RS1, RS2 and RS3. When we call<a name="line.720"></a>
+<span class="sourceLineNo">721</span>   * includeExcludeRegionServers(excludeFile, servers, false), RS1 is removed from regionServers<a name="line.721"></a>
+<span class="sourceLineNo">722</span>   * list so that regions can move to only RS2 and RS3.<a name="line.722"></a>
+<span class="sourceLineNo">723</span>   */<a name="line.723"></a>
+<span class="sourceLineNo">724</span>  private void includeExcludeRegionServers(String fileName, List&lt;ServerName&gt; regionServers,<a name="line.724"></a>
+<span class="sourceLineNo">725</span>    boolean isInclude) throws IOException {<a name="line.725"></a>
+<span class="sourceLineNo">726</span>    if (fileName != null) {<a name="line.726"></a>
+<span class="sourceLineNo">727</span>      List&lt;String&gt; servers = readServersFromFile(fileName);<a name="line.727"></a>
+<span class="sourceLineNo">728</span>      if (servers.isEmpty()) {<a name="line.728"></a>
+<span class="sourceLineNo">729</span>        LOG.warn("No servers provided in the file: {}." + fileName);<a name="line.729"></a>
+<span class="sourceLineNo">730</span>        return;<a name="line.730"></a>
+<span class="sourceLineNo">731</span>      }<a name="line.731"></a>
+<span class="sourceLineNo">732</span>      Iterator&lt;ServerName&gt; i = regionServers.iterator();<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      while (i.hasNext()) {<a name="line.733"></a>
+<span class="sourceLineNo">734</span>        String rs = i.next().getServerName();<a name="line.734"></a>
+<span class="sourceLineNo">735</span>        String rsPort = rs.split(ServerName.SERVERNAME_SEPARATOR)[0].toLowerCase() + ":"<a name="line.735"></a>
+<span class="sourceLineNo">736</span>          + rs.split(ServerName.SERVERNAME_SEPARATOR)[1];<a name="line.736"></a>
+<span class="sourceLineNo">737</span>        if (isInclude != servers.contains(rsPort)) {<a name="line.737"></a>
+<span class="sourceLineNo">738</span>          i.remove();<a name="line.738"></a>
+<span class="sourceLineNo">739</span>        }<a name="line.739"></a>
+<span class="sourceLineNo">740</span>      }<a name="line.740"></a>
+<span class="sourceLineNo">741</span>    }<a name="line.741"></a>
+<span class="sourceLineNo">742</span>  }<a name="line.742"></a>
+<span class="sourceLineNo">743</span><a name="line.743"></a>
+<span class="sourceLineNo">744</span>  /**<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   * Exclude master from list of RSs to move regions to<a name="line.745"></a>
+<span class="sourceLineNo">746</span>   */<a name="line.746"></a>
+<span class="sourceLineNo">747</span>  private void stripMaster(List&lt;ServerName&gt; regionServers) throws IOException {<a name="line.747"></a>
+<span class="sourceLineNo">748</span>    ServerName master = admin.getClusterMetrics(EnumSet.of(Option.MASTER)).getMasterName();<a name="line.748"></a>
+<span class="sourceLineNo">749</span>    stripServer(regionServers, master.getHostname(), master.getPort());<a name="line.749"></a>
+<span class="sourceLineNo">750</span>  }<a name="line.750"></a>
+<span class="sourceLineNo">751</span><a name="line.751"></a>
+<span class="sourceLineNo">752</span>  /**<a name="line.752"></a>
+<span class="sourceLineNo">753</span>   * Remove the servername whose hostname and port portion matches from the passed array of servers.<a name="line.753"></a>
+<span class="sourceLineNo">754</span>   * Returns as side-effect the servername removed.<a name="line.754"></a>
+<span class="sourceLineNo">755</span>   * @return server removed from list of Region Servers<a name="line.755"></a>
+<span class="sourceLineNo">756</span>   */<a name="line.756"></a>
+<span class="sourceLineNo">757</span>  private ServerName stripServer(List&lt;ServerName&gt; regionServers, String hostname, int port) {<a name="line.757"></a>
+<span class="sourceLineNo">758</span>    for (Iterator&lt;ServerName&gt; iter = regionServers.iterator(); iter.hasNext();) {<a name="line.758"></a>
+<span class="sourceLineNo">759</span>      ServerName server = iter.next();<a name="line.759"></a>
+<span class="sourceLineNo">760</span>      if (<a name="line.760"></a>
+<span class="sourceLineNo">761</span>        server.getAddress().getHostName().equalsIgnoreCase(hostname)<a name="line.761"></a>
+<span class="sourceLineNo">762</span>          &amp;&amp; server.getAddress().getPort() == port<a name="line.762"></a>
+<span class="sourceLineNo">763</span>      ) {<a name="line.763"></a>
+<span class="sourceLineNo">764</span>        iter.remove();<a name="line.764"></a>
+<span class="sourceLineNo">765</span>        return server;<a name="line.765"></a>
+<span class="sourceLineNo">766</span>      }<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    }<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    return null;<a name="line.768"></a>
+<span class="sourceLineNo">769</span>  }<a name="line.769"></a>
+<span class="sourceLineNo">770</span><a name="line.770"></a>
+<span class="sourceLineNo">771</span>  @Override<a name="line.771"></a>
+<span class="sourceLineNo">772</span>  protected void addOptions() {<a name="line.772"></a>
+<span class="sourceLineNo">773</span>    this.addRequiredOptWithArg("r", "regionserverhost", "region server &lt;hostname&gt;|&lt;hostname:port&gt;");<a name="line.773"></a>
+<span class="sourceLineNo">774</span>    this.addRequiredOptWithArg("o", "operation", "Expected: load/unload/unload_from_rack");<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    this.addOptWithArg("m", "maxthreads",<a name="line.775"></a>
+<span class="sourceLineNo">776</span>      "Define the maximum number of threads to use to unload and reload the regions");<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    this.addOptWithArg("x", "excludefile",<a name="line.777"></a>
+<span class="sourceLineNo">778</span>      "File with &lt;hostname:port&gt; per line to exclude as unload targets; default excludes only "<a name="line.778"></a>
+<span class="sourceLineNo">779</span>        + "target host; useful for rack decommisioning.");<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    this.addOptWithArg("d", "designatedfile",<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      "File with &lt;hostname:port&gt; per line as unload targets;" + "default is all online hosts");<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    this.addOptWithArg("f", "filename",<a name="line.782"></a>
+<span class="sourceLineNo">783</span>      "File to save regions list into unloading, or read from loading; "<a name="line.783"></a>
+<span class="sourceLineNo">784</span>        + "default /tmp/&lt;usernamehostname:port&gt;");<a name="line.784"></a>
+<span class="sourceLineNo">785</span>    this.addOptNoArg("n", "noack",<a name="line.785"></a>
+<span class="sourceLineNo">786</span>      "Turn on No-Ack mode(default: false) which won't check if region is online on target "<a name="line.786"></a>
+<span class="sourceLineNo">787</span>        + "RegionServer, hence best effort. This is more performant in unloading and loading "<a name="line.787"></a>
+<span class="sourceLineNo">788</span>        + "but might lead to region being unavailable for some time till master reassigns it "<a name="line.788"></a>
+<span class="sourceLineNo">789</span>        + "in case the move failed");<a name="line.789"></a>
+<span class="sourceLineNo">790</span>    this.addOptWithArg("t", "timeout", "timeout in seconds after which the tool will exit "<a name="line.790"></a>
+<span class="sourceLineNo">791</span>      + "irrespective of whether it finished or not;default Integer.MAX_VALUE");<a name="line.791"></a>
+<span class="sourceLineNo">792</span>  }<a name="line.792"></a>
+<span class="sourceLineNo">793</span><a name="line.793"></a>
+<span class="sourceLineNo">794</span>  @Override<a name="line.794"></a>
+<span class="sourceLineNo">795</span>  protected void processOptions(CommandLine cmd) {<a name="line.795"></a>
+<span class="sourceLineNo">796</span>    String hostname = cmd.getOptionValue("r");<a name="line.796"></a>
+<span class="sourceLineNo">797</span>    rmbuilder = new RegionMoverBuilder(hostname);<a name="line.797"></a>
+<span class="sourceLineNo">798</span>    if (cmd.hasOption('m')) {<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      rmbuilder.maxthreads(Integer.parseInt(cmd.getOptionValue('m')));<a name="line.799"></a>
+<span class="sourceLineNo">800</span>    }<a name="line.800"></a>
+<span class="sourceLineNo">801</span>    if (cmd.hasOption('n')) {<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      rmbuilder.ack(false);<a name="line.802"></a>
+<span class="sourceLineNo">803</span>    }<a name="line.803"></a>
+<span class="sourceLineNo">804</span>    if (cmd.hasOption('f')) {<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      rmbuilder.filename(cmd.getOptionValue('f'));<a name="line.805"></a>
+<span class="sourceLineNo">806</span>    }<a name="line.806"></a>
+<span class="sourceLineNo">807</span>    if (cmd.hasOption('x')) {<a name="line.807"></a>
+<span class="sourceLineNo">808</span>      rmbuilder.excludeFile(cmd.getOptionValue('x'));<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    }<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    if (cmd.hasOption('d')) {<a name="line.810"></a>
+<span class="sourceLineNo">811</span>      rmbuilder.designatedFile(cmd.getOptionValue('d'));<a name="line.811"></a>
+<span class="sourceLineNo">812</span>    }<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    if (cmd.hasOption('t')) {<a name="line.813"></a>
+<span class="sourceLineNo">814</span>      rmbuilder.timeout(Integer.parseInt(cmd.getOptionValue('t')));<a name="line.814"></a>
+<span class="sourceLineNo">815</span>    }<a name="line.815"></a>
+<span class="sourceLineNo">816</span>    this.loadUnload = cmd.getOptionValue("o").toLowerCase(Locale.ROOT);<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  @Override<a name="line.819"></a>
+<span class="sourceLineNo">820</span>  protected int doWork() throws Exception {<a name="line.820"></a>
+<span class="sourceLineNo">821</span>    boolean success;<a name="line.821"></a>
+<span class="sourceLineNo">822</span>    try (RegionMover rm = rmbuilder.build()) {<a name="line.822"></a>
+<span class="sourceLineNo">823</span>      if (loadUnload.equalsIgnoreCase("load")) {<a name="line.823"></a>
+<span class="sourceLineNo">824</span>        success = rm.load();<a name="line.824"></a>
+<span class="sourceLineNo">825</span>      } else if (loadUnload.equalsIgnoreCase("unload")) {<a name="line.825"></a>
+<span class="sourceLineNo">826</span>        success = rm.unload();<a name="line.826"></a>
+<span class="sourceLineNo">827</span>      } else if (loadUnload.equalsIgnoreCase("unload_from_rack")) {<a name="line.827"></a>
+<span class="sourceLineNo">828</span>        success = rm.unloadFromRack();<a name="line.828"></a>
+<span class="sourceLineNo">829</span>      } else {<a name="line.829"></a>
+<span class="sourceLineNo">830</span>        printUsage();<a name="line.830"></a>
+<span class="sourceLineNo">831</span>        success = false;<a name="line.831"></a>
+<span class="sourceLineNo">832</span>      }<a name="line.832"></a>
+<span class="sourceLineNo">833</span>    }<a name="line.833"></a>
+<span class="sourceLineNo">834</span>    return (success ? 0 : 1);<a name="line.834"></a>
+<span class="sourceLineNo">835</span>  }<a name="line.835"></a>
+<span class="sourceLineNo">836</span><a name="line.836"></a>
+<span class="sourceLineNo">837</span>  public static void main(String[] args) {<a name="line.837"></a>
+<span class="sourceLineNo">838</span>    try (RegionMover mover = new RegionMover()) {<a name="line.838"></a>
+<span class="sourceLineNo">839</span>      mover.doStaticMain(args);<a name="line.839"></a>
+<span class="sourceLineNo">840</span>    }<a name="line.840"></a>
+<span class="sourceLineNo">841</span>  }<a name="line.841"></a>
+<span class="sourceLineNo">842</span>}<a name="line.842"></a>
 
 
 
diff --git a/book.html b/book.html
index c6f00f10c7e..255bbeb80ea 100644
--- a/book.html
+++ b/book.html
@@ -48002,7 +48002,7 @@ org/apache/hadoop/hbase/security/access/AccessControlClient.revoke:(Lorg/apache/
 <div id="footer">
 <div id="footer-text">
 Version 3.0.0-alpha-4-SNAPSHOT<br>
-Last updated 2022-09-21 14:30:51 UTC
+Last updated 2022-09-22 14:33:13 UTC
 </div>
 </div>
 <script type="text/x-mathjax-config">
diff --git a/bulk-loads.html b/bulk-loads.html
index b2e5df30371..81b5298e262 100644
--- a/bulk-loads.html
+++ b/bulk-loads.html
@@ -180,7 +180,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/checkstyle-aggregate.html b/checkstyle-aggregate.html
index d88bf84524f..91f6065237f 100644
--- a/checkstyle-aggregate.html
+++ b/checkstyle-aggregate.html
@@ -173,7 +173,7 @@
 <th><figure><img src="images/icon_warning_sml.gif" alt="" /></figure>&#160;Warnings</th>
 <th><figure><img src="images/icon_error_sml.gif" alt="" /></figure>&#160;Errors</th></tr>
 <tr class="b">
-<td>4761</td>
+<td>4764</td>
 <td>0</td>
 <td>0</td>
 <td>1758</td></tr></table></section><section>
@@ -10382,7 +10382,7 @@
 <td>blocks</td>
 <td>NeedBraces</td>
 <td>'if' construct must use '{}'s.</td>
-<td>539</td></tr></table></section><section>
+<td>544</td></tr></table></section><section>
 <h3 id="org.apache.hadoop.hbase.master.SnapshotOfRegionAssignmentFromMeta.java">org/apache/hadoop/hbase/master/SnapshotOfRegionAssignmentFromMeta.java</h3>
 <table border="0" class="table table-striped">
 <tr class="b">
@@ -18010,7 +18010,7 @@
 <td>design</td>
 <td>FinalClass</td>
 <td>Class RegionMover should be declared as final.</td>
-<td>82</td></tr></table></section><section>
+<td>84</td></tr></table></section><section>
 <h3 id="org.apache.hadoop.hbase.util.RegionSplitCalculator.java">org/apache/hadoop/hbase/util/RegionSplitCalculator.java</h3>
 <table border="0" class="table table-striped">
 <tr class="b">
@@ -18801,7 +18801,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/checkstyle.rss b/checkstyle.rss
index cd8719513aa..8cf213862f2 100644
--- a/checkstyle.rss
+++ b/checkstyle.rss
@@ -25,7 +25,7 @@ under the License.
     <language>en-us</language>
     <copyright>&#169;2007 - 2022 The Apache Software Foundation</copyright>
     <item>
-      <title>File: 4761,
+      <title>File: 4764,
              Errors: 1758,
              Warnings: 0,
              Infos: 0
@@ -29681,6 +29681,20 @@ under the License.
                 <td>
                   0
                 </td>
+              </tr>
+                          <tr>
+                <td>
+                  <a href="https://hbase.apache.org/checkstyle.html#org.apache.hadoop.hbase.regionserver.TestRegionServerUseIp.java">org/apache/hadoop/hbase/regionserver/TestRegionServerUseIp.java</a>
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
               </tr>
                           <tr>
                 <td>
@@ -30661,6 +30675,20 @@ under the License.
                 <td>
                   0
                 </td>
+              </tr>
+                          <tr>
+                <td>
+                  <a href="https://hbase.apache.org/checkstyle.html#org.apache.hadoop.hbase.util.TestRegionMoverUseIp.java">org/apache/hadoop/hbase/util/TestRegionMoverUseIp.java</a>
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
               </tr>
                           <tr>
                 <td>
@@ -52025,6 +52053,20 @@ under the License.
                 <td>
                   0
                 </td>
+              </tr>
+                          <tr>
+                <td>
+                  <a href="https://hbase.apache.org/checkstyle.html#org.apache.hadoop.hbase.master.TestMasterUseIp.java">org/apache/hadoop/hbase/master/TestMasterUseIp.java</a>
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
+                <td>
+                  0
+                </td>
               </tr>
                           <tr>
                 <td>
diff --git a/coc.html b/coc.html
index 01b60401e27..9ce3985558d 100644
--- a/coc.html
+++ b/coc.html
@@ -248,7 +248,7 @@ email to <a class="externalLink" href="mailto:private@hbase.apache.org">the priv
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependencies.html b/dependencies.html
index c08ac05c807..84e95bbb72c 100644
--- a/dependencies.html
+++ b/dependencies.html
@@ -313,7 +313,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-convergence.html b/dependency-convergence.html
index a88d4af7b20..ea3697f843d 100644
--- a/dependency-convergence.html
+++ b/dependency-convergence.html
@@ -1013,7 +1013,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-info.html b/dependency-info.html
index c317ac27fe2..8e35ed35414 100644
--- a/dependency-info.html
+++ b/dependency-info.html
@@ -195,7 +195,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/dependency-management.html b/dependency-management.html
index 3144c4d3f7b..875999d4e7f 100644
--- a/dependency-management.html
+++ b/dependency-management.html
@@ -1319,7 +1319,7 @@
         <div class="row">
             <p>Copyright &copy;2007&#x2013;2022
 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
-All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-21</li>
+All rights reserved.        <li id="publishDate" class="pull-right">Last Published: 2022-09-22</li>
 </p>
         </div>
         <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a>
diff --git a/devapidocs/constant-values.html b/devapidocs/constant-values.html
index 9a62be9734e..27aa5b27090 100644
--- a/devapidocs/constant-values.html
+++ b/devapidocs/constant-values.html
@@ -1924,6 +1924,20 @@
 <td class="colLast"><code>"hbase.server.scanner.max.result.size"</code></td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><a name="org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT">
+<!--   -->
+</a><code>public&nbsp;static&nbsp;final&nbsp;boolean</code></td>
+<td><code><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_DEFAULT">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></code></td>
+<td class="colLast"><code>false</code></td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><a name="org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_KEY">
+<!--   -->
+</a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td><code><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY">HBASE_SERVER_USEIP_ENABLED_KEY</a></code></td>
+<td class="colLast"><code>"hbase.server.useip.enabled"</code></td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><a name="org.apache.hadoop.hbase.HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK">
 <!--   -->
 </a><code>public&nbsp;static&nbsp;final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
diff --git a/devapidocs/index-all.html b/devapidocs/index-all.html
index 3ab633e2607..7ae363aee1c 100644
--- a/devapidocs/index-all.html
+++ b/devapidocs/index-all.html
@@ -66332,6 +66332,15 @@
 <dd>
 <div class="block">Parameter name for maximum number of bytes returned when calling a scanner's next method.</div>
 </dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_DEFAULT">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></span> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HConstants.html" title="class in org.apache.hadoop.hbase">HConstants</a></dt>
+<dd>
+<div class="block">Default value of <a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY"><code>HConstants.HBASE_SERVER_USEIP_ENABLED_KEY</code></a></div>
+</dd>
+<dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY">HBASE_SERVER_USEIP_ENABLED_KEY</a></span> - Static variable in class org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/HConstants.html" title="class in org.apache.hadoop.hbase">HConstants</a></dt>
+<dd>
+<div class="block">In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not
+ be able to resolve the hostname of the newly added node.</div>
+</dd>
 <dt><span class="memberNameLink"><a href="org/apache/hadoop/hbase/master/snapshot/SnapshotManager.html#HBASE_SNAPSHOT_ENABLED">HBASE_SNAPSHOT_ENABLED</a></span> - Static variable in class org.apache.hadoop.hbase.master.snapshot.<a href="org/apache/hadoop/hbase/master/snapshot/SnapshotManager.html" title="class in org.apache.hadoop.hbase.master.snapshot">SnapshotManager</a></dt>
 <dd>
 <div class="block">Enable or disable snapshot support</div>
diff --git a/devapidocs/org/apache/hadoop/hbase/HBaseServerBase.html b/devapidocs/org/apache/hadoop/hbase/HBaseServerBase.html
index babc752c674..99e730a70da 100644
--- a/devapidocs/org/apache/hadoop/hbase/HBaseServerBase.html
+++ b/devapidocs/org/apache/hadoop/hbase/HBaseServerBase.html
@@ -1003,7 +1003,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>putUpWebUI</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.307">putUpWebUI</a>()
+<pre>private&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.313">putUpWebUI</a>()
                  throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Puts up the webui.</div>
 <dl>
@@ -1018,7 +1018,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>setAbortRequested</h4>
-<pre>protected final&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.362">setAbortRequested</a>()</pre>
+<pre>protected final&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.368">setAbortRequested</a>()</pre>
 <div class="block">Sets the abort state if not already set.</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1033,7 +1033,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>isStopped</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.367">isStopped</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.373">isStopped</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Stoppable.html#isStopped--">Stoppable</a></code></span></div>
 <div class="block">Returns True if <a href="../../../../org/apache/hadoop/hbase/Stoppable.html#stop-java.lang.String-"><code>Stoppable.stop(String)</code></a> has been closed.</div>
 <dl>
@@ -1048,7 +1048,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>isAborted</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.372">isAborted</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.378">isAborted</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Abortable.html#isAborted--">Abortable</a></code></span></div>
 <div class="block">Check if the server or client was aborted.</div>
 <dl>
@@ -1065,7 +1065,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getConfiguration</h4>
-<pre>public&nbsp;org.apache.hadoop.conf.Configuration&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.377">getConfiguration</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.conf.Configuration&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.383">getConfiguration</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getConfiguration--">Server</a></code></span></div>
 <div class="block">Gets the configuration object for this server.</div>
 <dl>
@@ -1080,7 +1080,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getAsyncClusterConnection</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/client/AsyncClusterConnection.html" title="interface in org.apache.hadoop.hbase.client">AsyncClusterConnection</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.382">getAsyncClusterConnection</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/client/AsyncClusterConnection.html" title="interface in org.apache.hadoop.hbase.client">AsyncClusterConnection</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.388">getAsyncClusterConnection</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getAsyncClusterConnection--">Server</a></code></span></div>
 <div class="block">Returns a reference to the servers' async cluster connection.
  <p/>
@@ -1098,7 +1098,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getZooKeeper</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/zookeeper/ZKWatcher.html" title="class in org.apache.hadoop.hbase.zookeeper">ZKWatcher</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.387">getZooKeeper</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/zookeeper/ZKWatcher.html" title="class in org.apache.hadoop.hbase.zookeeper">ZKWatcher</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.393">getZooKeeper</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getZooKeeper--">Server</a></code></span></div>
 <div class="block">Gets the ZooKeeper instance for this server.</div>
 <dl>
@@ -1113,7 +1113,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>shutdownChore</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.391">shutdownChore</a>(<a href="../../../../org/apache/hadoop/hbase/ScheduledChore.html" title="class in org.apache.hadoop.hbase">ScheduledChore</a>&nbsp;chore)</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.397">shutdownChore</a>(<a href="../../../../org/apache/hadoop/hbase/ScheduledChore.html" title="class in org.apache.hadoop.hbase">ScheduledChore</a>&nbsp;chore)</pre>
 </li>
 </ul>
 <a name="initializeMemStoreChunkCreator-org.apache.hadoop.hbase.regionserver.HeapMemoryManager-">
@@ -1122,7 +1122,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>initializeMemStoreChunkCreator</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.397">initializeMemStoreChunkCreator</a>(<a href="../../../../org/apache/hadoop/hbase/regionserver/HeapMemoryManager.html" title="class in org.apache.hadoop.hbase.regionserver">HeapMemoryManager</a>&nbsp;hMemManager)</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.403">initializeMemStoreChunkCreator</a>(<a href="../../../../org/apache/hadoop/hbase/regionserver/HeapMemoryManager.html" title="class in org.apache.hadoop.hbase.regionserver">HeapMemoryManager</a>&nbsp;hMemManager)</pre>
 </li>
 </ul>
 <a name="stopChores--">
@@ -1131,7 +1131,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>stopChores</h4>
-<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.420">stopChores</a>()</pre>
+<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.426">stopChores</a>()</pre>
 </li>
 </ul>
 <a name="stopChoreService--">
@@ -1140,7 +1140,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>stopChoreService</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.422">stopChoreService</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.428">stopChoreService</a>()</pre>
 </li>
 </ul>
 <a name="stopExecutorService--">
@@ -1149,7 +1149,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>stopExecutorService</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.433">stopExecutorService</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.439">stopExecutorService</a>()</pre>
 </li>
 </ul>
 <a name="closeClusterConnection--">
@@ -1158,7 +1158,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>closeClusterConnection</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.440">closeClusterConnection</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.446">closeClusterConnection</a>()</pre>
 </li>
 </ul>
 <a name="stopInfoServer--">
@@ -1167,7 +1167,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>stopInfoServer</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.453">stopInfoServer</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.459">stopInfoServer</a>()</pre>
 </li>
 </ul>
 <a name="closeZooKeeper--">
@@ -1176,7 +1176,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>closeZooKeeper</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.464">closeZooKeeper</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.470">closeZooKeeper</a>()</pre>
 </li>
 </ul>
 <a name="closeTableDescriptors--">
@@ -1185,7 +1185,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>closeTableDescriptors</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.471">closeTableDescriptors</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.477">closeTableDescriptors</a>()</pre>
 </li>
 </ul>
 <a name="installShutdownHook--">
@@ -1194,7 +1194,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>installShutdownHook</h4>
-<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.486">installShutdownHook</a>()</pre>
+<pre>protected final&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.492">installShutdownHook</a>()</pre>
 <div class="block">In order to register ShutdownHook, this method is called when HMaster and HRegionServer are
  started. For details, please refer to HBASE-26951</div>
 </li>
@@ -1205,7 +1205,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>isShutdownHookInstalled</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.493">isShutdownHookInstalled</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.499">isShutdownHookInstalled</a>()</pre>
 </li>
 </ul>
 <a name="getServerName--">
@@ -1214,7 +1214,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getServerName</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.498">getServerName</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.504">getServerName</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getServerName--">Server</a></code></span></div>
 <div class="block">Returns The unique server name for this server.</div>
 <dl>
@@ -1229,7 +1229,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getChoreService</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/ChoreService.html" title="class in org.apache.hadoop.hbase">ChoreService</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.503">getChoreService</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/ChoreService.html" title="class in org.apache.hadoop.hbase">ChoreService</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.509">getChoreService</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getChoreService--">Server</a></code></span></div>
 <div class="block">Returns The <a href="../../../../org/apache/hadoop/hbase/ChoreService.html" title="class in org.apache.hadoop.hbase"><code>ChoreService</code></a> instance for this server</div>
 <dl>
@@ -1244,7 +1244,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getTableDescriptors</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/TableDescriptors.html" title="interface in org.apache.hadoop.hbase">TableDescriptors</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.508">getTableDescriptors</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/TableDescriptors.html" title="interface in org.apache.hadoop.hbase">TableDescriptors</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.514">getTableDescriptors</a>()</pre>
 <div class="block">Returns Return table descriptors implementation.</div>
 </li>
 </ul>
@@ -1254,7 +1254,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getExecutorService</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/executor/ExecutorService.html" title="class in org.apache.hadoop.hbase.executor">ExecutorService</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.512">getExecutorService</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/executor/ExecutorService.html" title="class in org.apache.hadoop.hbase.executor">ExecutorService</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.518">getExecutorService</a>()</pre>
 </li>
 </ul>
 <a name="getAccessChecker--">
@@ -1263,7 +1263,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getAccessChecker</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/security/access/AccessChecker.html" title="class in org.apache.hadoop.hbase.security.access">AccessChecker</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.516">getAccessChecker</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/security/access/AccessChecker.html" title="class in org.apache.hadoop.hbase.security.access">AccessChecker</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.522">getAccessChecker</a>()</pre>
 </li>
 </ul>
 <a name="getZKPermissionWatcher--">
@@ -1272,7 +1272,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getZKPermissionWatcher</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/security/access/ZKPermissionWatcher.html" title="class in org.apache.hadoop.hbase.security.access">ZKPermissionWatcher</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.520">getZKPermissionWatcher</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/security/access/ZKPermissionWatcher.html" title="class in org.apache.hadoop.hbase.security.access">ZKPermissionWatcher</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.526">getZKPermissionWatcher</a>()</pre>
 </li>
 </ul>
 <a name="getCoordinatedStateManager--">
@@ -1281,7 +1281,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getCoordinatedStateManager</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/CoordinatedStateManager.html" title="interface in org.apache.hadoop.hbase">CoordinatedStateManager</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.525">getCoordinatedStateManager</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/CoordinatedStateManager.html" title="interface in org.apache.hadoop.hbase">CoordinatedStateManager</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.531">getCoordinatedStateManager</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getCoordinatedStateManager--">Server</a></code></span></div>
 <div class="block">Get CoordinatedStateManager instance for this server.</div>
 <dl>
@@ -1296,7 +1296,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>createConnection</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/client/Connection.html" title="interface in org.apache.hadoop.hbase.client">Connection</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.530">createConnection</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/client/Connection.html" title="interface in org.apache.hadoop.hbase.client">Connection</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.536">createConnection</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
@@ -1312,7 +1312,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getDataRootDir</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.536">getDataRootDir</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.542">getDataRootDir</a>()</pre>
 <div class="block">Returns Return the rootDir.</div>
 </li>
 </ul>
@@ -1322,7 +1322,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getFileSystem</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.541">getFileSystem</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.547">getFileSystem</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from interface:&nbsp;<code><a href="../../../../org/apache/hadoop/hbase/Server.html#getFileSystem--">Server</a></code></span></div>
 <div class="block">Returns Return the FileSystem object used (can return null!).</div>
 <dl>
@@ -1337,7 +1337,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getWALRootDir</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.546">getWALRootDir</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.Path&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.552">getWALRootDir</a>()</pre>
 <div class="block">Returns Return the walRootDir.</div>
 </li>
 </ul>
@@ -1347,7 +1347,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getWALFileSystem</h4>
-<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.551">getWALFileSystem</a>()</pre>
+<pre>public&nbsp;org.apache.hadoop.fs.FileSystem&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.557">getWALFileSystem</a>()</pre>
 <div class="block">Returns Return the walFs.</div>
 </li>
 </ul>
@@ -1357,7 +1357,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>isClusterUp</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.556">isClusterUp</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.562">isClusterUp</a>()</pre>
 <div class="block">Returns True if the cluster is up.</div>
 </li>
 </ul>
@@ -1367,7 +1367,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getStartcode</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.561">getStartcode</a>()</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.567">getStartcode</a>()</pre>
 <div class="block">Returns time stamp in millis of when this server was started</div>
 </li>
 </ul>
@@ -1377,7 +1377,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getInfoServer</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/http/InfoServer.html" title="class in org.apache.hadoop.hbase.http">InfoServer</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.565">getInfoServer</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/http/InfoServer.html" title="class in org.apache.hadoop.hbase.http">InfoServer</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.571">getInfoServer</a>()</pre>
 </li>
 </ul>
 <a name="getMsgInterval--">
@@ -1386,7 +1386,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getMsgInterval</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.569">getMsgInterval</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.575">getMsgInterval</a>()</pre>
 </li>
 </ul>
 <a name="getNamedQueueRecorder--">
@@ -1395,7 +1395,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getNamedQueueRecorder</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/namequeues/NamedQueueRecorder.html" title="class in org.apache.hadoop.hbase.namequeues">NamedQueueRecorder</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.576">getNamedQueueRecorder</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/namequeues/NamedQueueRecorder.html" title="class in org.apache.hadoop.hbase.namequeues">NamedQueueRecorder</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.582">getNamedQueueRecorder</a>()</pre>
 <div class="block">get NamedQueue Provider to add different logs to ringbuffer n</div>
 </li>
 </ul>
@@ -1405,7 +1405,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getRpcServer</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/ipc/RpcServerInterface.html" title="interface in org.apache.hadoop.hbase.ipc">RpcServerInterface</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.580">getRpcServer</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/ipc/RpcServerInterface.html" title="interface in org.apache.hadoop.hbase.ipc">RpcServerInterface</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.586">getRpcServer</a>()</pre>
 </li>
 </ul>
 <a name="getEventLoopGroupConfig--">
@@ -1414,7 +1414,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getEventLoopGroupConfig</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/util/NettyEventLoopGroupConfig.html" title="class in org.apache.hadoop.hbase.util">NettyEventLoopGroupConfig</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.584">getEventLoopGroupConfig</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/util/NettyEventLoopGroupConfig.html" title="class in org.apache.hadoop.hbase.util">NettyEventLoopGroupConfig</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.590">getEventLoopGroupConfig</a>()</pre>
 </li>
 </ul>
 <a name="getRpcServices--">
@@ -1423,7 +1423,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getRpcServices</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/HBaseServerBase.html" title="type parameter in HBaseServerBase">R</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.588">getRpcServices</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/HBaseServerBase.html" title="type parameter in HBaseServerBase">R</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.594">getRpcServices</a>()</pre>
 </li>
 </ul>
 <a name="getMetaRegionLocationCache--">
@@ -1432,7 +1432,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getMetaRegionLocationCache</h4>
-<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/MetaRegionLocationCache.html" title="class in org.apache.hadoop.hbase">MetaRegionLocationCache</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.594">getMetaRegionLocationCache</a>()</pre>
+<pre>public&nbsp;<a href="../../../../org/apache/hadoop/hbase/MetaRegionLocationCache.html" title="class in org.apache.hadoop.hbase">MetaRegionLocationCache</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.600">getMetaRegionLocationCache</a>()</pre>
 </li>
 </ul>
 <a name="updateConfiguration--">
@@ -1441,7 +1441,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>updateConfiguration</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.601">updateConfiguration</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.607">updateConfiguration</a>()</pre>
 <div class="block">Reload the configuration from disk.</div>
 </li>
 </ul>
@@ -1451,7 +1451,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>toString</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.609">toString</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.615">toString</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Overrides:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html?is-external=true#toString--" title="class or interface in java.lang">toString</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html?is-external=true" title="class or interface in java.lang">Thread</a></code></dd>
@@ -1464,7 +1464,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>canCreateBaseZNode</h4>
-<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.613">canCreateBaseZNode</a>()</pre>
+<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.619">canCreateBaseZNode</a>()</pre>
 </li>
 </ul>
 <a name="getProcessName--">
@@ -1473,7 +1473,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getProcessName</h4>
-<pre>protected abstract&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.615">getProcessName</a>()</pre>
+<pre>protected abstract&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.621">getProcessName</a>()</pre>
 </li>
 </ul>
 <a name="createRpcServices--">
@@ -1482,7 +1482,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>createRpcServices</h4>
-<pre>protected abstract&nbsp;<a href="../../../../org/apache/hadoop/hbase/HBaseServerBase.html" title="type parameter in HBaseServerBase">R</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.617">createRpcServices</a>()
+<pre>protected abstract&nbsp;<a href="../../../../org/apache/hadoop/hbase/HBaseServerBase.html" title="type parameter in HBaseServerBase">R</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.623">createRpcServices</a>()
                                 throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1496,7 +1496,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getUseThisHostnameInstead</h4>
-<pre>protected abstract&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.619">getUseThisHostnameInstead</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)
+<pre>protected abstract&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.625">getUseThisHostnameInstead</a>(org.apache.hadoop.conf.Configuration&nbsp;conf)
                                              throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1510,7 +1510,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>login</h4>
-<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.621">login</a>(<a href="../../../../org/apache/hadoop/hbase/security/UserProvider.html" title="class in org.apache.hadoop.hbase.security">UserProvider</a>&nbsp;user,
+<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.627">login</a>(<a href="../../../../org/apache/hadoop/hbase/security/UserProvider.html" title="class in org.apache.hadoop.hbase.security">UserProvider</a>&nbsp;user,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;host)
                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
@@ -1525,7 +1525,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>createNamedQueueRecord</h4>
-<pre>protected abstract&nbsp;<a href="../../../../org/apache/hadoop/hbase/namequeues/NamedQueueRecorder.html" title="class in org.apache.hadoop.hbase.namequeues">NamedQueueRecorder</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.623">createNamedQueueRecord</a>()</pre>
+<pre>protected abstract&nbsp;<a href="../../../../org/apache/hadoop/hbase/namequeues/NamedQueueRecorder.html" title="class in org.apache.hadoop.hbase.namequeues">NamedQueueRecorder</a>&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.629">createNamedQueueRecord</a>()</pre>
 </li>
 </ul>
 <a name="configureInfoServer-org.apache.hadoop.hbase.http.InfoServer-">
@@ -1534,7 +1534,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>configureInfoServer</h4>
-<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.625">configureInfoServer</a>(<a href="../../../../org/apache/hadoop/hbase/http/InfoServer.html" title="class in org.apache.hadoop.hbase.http">InfoServer</a>&nbsp;infoServer)</pre>
+<pre>protected abstract&nbsp;void&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.631">configureInfoServer</a>(<a href="../../../../org/apache/hadoop/hbase/http/InfoServer.html" title="class in org.apache.hadoop.hbase.http">InfoServer</a>&nbsp;infoServer)</pre>
 </li>
 </ul>
 <a name="getDumpServlet--">
@@ -1543,7 +1543,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>getDumpServlet</h4>
-<pre>protected abstract&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a>&lt;? extends javax.servlet.http.HttpServlet&gt;&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.627">getDumpServlet</a>()</pre>
+<pre>protected abstract&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html?is-external=true" title="class or interface in java.lang">Class</a>&lt;? extends javax.servlet.http.HttpServlet&gt;&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.633">getDumpServlet</a>()</pre>
 </li>
 </ul>
 <a name="canUpdateTableDescriptor--">
@@ -1552,7 +1552,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>canUpdateTableDescriptor</h4>
-<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.629">canUpdateTableDescriptor</a>()</pre>
+<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.635">canUpdateTableDescriptor</a>()</pre>
 </li>
 </ul>
 <a name="cacheTableDescriptor--">
@@ -1561,7 +1561,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockList">
 <li class="blockList">
 <h4>cacheTableDescriptor</h4>
-<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.631">cacheTableDescriptor</a>()</pre>
+<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.637">cacheTableDescriptor</a>()</pre>
 </li>
 </ul>
 <a name="clusterMode--">
@@ -1570,7 +1570,7 @@ implements <a href="../../../../org/apache/hadoop/hbase/Server.html" title="inte
 <ul class="blockListLast">
 <li class="blockList">
 <h4>clusterMode</h4>
-<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.633">clusterMode</a>()</pre>
+<pre>protected abstract&nbsp;boolean&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HBaseServerBase.html#line.639">clusterMode</a>()</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/HConstants.html b/devapidocs/org/apache/hadoop/hbase/HConstants.html
index f8433412e74..79a909a0e75 100644
--- a/devapidocs/org/apache/hadoop/hbase/HConstants.html
+++ b/devapidocs/org/apache/hadoop/hbase/HConstants.html
@@ -1259,6 +1259,19 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 </td>
 </tr>
 <tr class="rowColor">
+<td class="colFirst"><code>static boolean</code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_DEFAULT">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></span></code>
+<div class="block">Default value of <a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY"><code>HBASE_SERVER_USEIP_ENABLED_KEY</code></a></div>
+</td>
+</tr>
+<tr class="altColor">
+<td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
+<td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY">HBASE_SERVER_USEIP_ENABLED_KEY</a></span></code>
+<div class="block">In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not
+ be able to resolve the hostname of the newly added node.</div>
+</td>
+</tr>
+<tr class="rowColor">
 <td class="colFirst"><code>static <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a></code></td>
 <td class="colLast"><code><span class="memberNameLink"><a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SPLIT_WAL_COORDINATED_BY_ZK">HBASE_SPLIT_WAL_COORDINATED_BY_ZK</a></span></code>
 <div class="block"><span class="deprecatedLabel">Deprecated.</span>&nbsp;
@@ -7818,7 +7831,7 @@ public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop
 <a name="BATCH_ROWS_THRESHOLD_DEFAULT">
 <!--   -->
 </a>
-<ul class="blockListLast">
+<ul class="blockList">
 <li class="blockList">
 <h4>BATCH_ROWS_THRESHOLD_DEFAULT</h4>
 <pre>public static final&nbsp;int <a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1572">BATCH_ROWS_THRESHOLD_DEFAULT</a></pre>
@@ -7829,6 +7842,40 @@ public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop
 </dl>
 </li>
 </ul>
+<a name="HBASE_SERVER_USEIP_ENABLED_KEY">
+<!--   -->
+</a>
+<ul class="blockList">
+<li class="blockList">
+<h4>HBASE_SERVER_USEIP_ENABLED_KEY</h4>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1583">HBASE_SERVER_USEIP_ENABLED_KEY</a></pre>
+<div class="block">In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not
+ be able to resolve the hostname of the newly added node. If the network is interconnected, the
+ client can actually access the HBase cluster nodes through ip. However, since the HBase client
+ obtains the Master/RS address info from or the ZK or the meta table, so the Master/RS of the
+ HBase cluster needs to expose the service with ip instead of the hostname. Therefore, We can
+ use hostname by default, but at the same time, we can also provide a config to support whether
+ to use ip for Master/RS service. See HBASE-27304 for details.</div>
+<dl>
+<dt><span class="seeLabel">See Also:</span></dt>
+<dd><a href="../../../../constant-values.html#org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_KEY">Constant Field Values</a></dd>
+</dl>
+</li>
+</ul>
+<a name="HBASE_SERVER_USEIP_ENABLED_DEFAULT">
+<!--   -->
+</a>
+<ul class="blockListLast">
+<li class="blockList">
+<h4>HBASE_SERVER_USEIP_ENABLED_DEFAULT</h4>
+<pre>public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1588">HBASE_SERVER_USEIP_ENABLED_DEFAULT</a></pre>
+<div class="block">Default value of <a href="../../../../org/apache/hadoop/hbase/HConstants.html#HBASE_SERVER_USEIP_ENABLED_KEY"><code>HBASE_SERVER_USEIP_ENABLED_KEY</code></a></div>
+<dl>
+<dt><span class="seeLabel">See Also:</span></dt>
+<dd><a href="../../../../constant-values.html#org.apache.hadoop.hbase.HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT">Constant Field Values</a></dd>
+</dl>
+</li>
+</ul>
 </li>
 </ul>
 <!-- ========= CONSTRUCTOR DETAIL ======== -->
@@ -7843,7 +7890,7 @@ public static final&nbsp;boolean <a href="../../../../src-html/org/apache/hadoop
 <ul class="blockListLast">
 <li class="blockList">
 <h4>HConstants</h4>
-<pre>private&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1574">HConstants</a>()</pre>
+<pre>private&nbsp;<a href="../../../../src-html/org/apache/hadoop/hbase/HConstants.html#line.1590">HConstants</a>()</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
index 43ded693db3..9849e3f56fc 100644
--- a/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/backup/package-tree.html
@@ -166,10 +166,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupRestoreConstants.BackupCommand.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupRestoreConstants.BackupCommand</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupState.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupRestoreConstants.BackupCommand.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupRestoreConstants.BackupCommand</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupType.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.backup.<a href="../../../../../org/apache/hadoop/hbase/backup/BackupInfo.BackupPhase.html" title="enum in org.apache.hadoop.hbase.backup"><span class="typeNameLink">BackupInfo.BackupPhase</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html b/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html
index 192324858b4..0a0fcc3460b 100644
--- a/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/chaos/package-tree.html
@@ -103,8 +103,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.chaos.<a href="../../../../../org/apache/hadoop/hbase/chaos/ChaosService.ExecutorAction.html" title="enum in org.apache.hadoop.hbase.chaos"><span class="typeNameLink">ChaosService.ExecutorAction</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.chaos.<a href="../../../../../org/apache/hadoop/hbase/chaos/ChaosService.ChaosServiceName.html" title="enum in org.apache.hadoop.hbase.chaos"><span class="typeNameLink">ChaosService.ChaosServiceName</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.chaos.<a href="../../../../../org/apache/hadoop/hbase/chaos/ChaosService.ExecutorAction.html" title="enum in org.apache.hadoop.hbase.chaos"><span class="typeNameLink">ChaosService.ExecutorAction</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
index 43bbd484e31..907efa3aebb 100644
--- a/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/client/package-tree.html
@@ -469,24 +469,24 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Scan.ReadType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Scan.ReadType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactionState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactionState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.FilterByOperator.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.FilterByOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.Type.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/ServerType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">ServerType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AbstractResponse.ResponseType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AbstractResponse.ResponseType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MobCompactPartitionPolicy.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MobCompactPartitionPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RequestController.ReturnCode.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RequestController.ReturnCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/TableState.State.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">TableState.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Consistency.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Consistency</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanResumerState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.Type.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Durability.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Durability</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/CompactType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">CompactType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/MasterSwitchType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">MasterSwitchType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/LogQueryFilter.FilterByOperator.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">LogQueryFilter.FilterByOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/SnapshotType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">SnapshotType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/Scan.ReadType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">Scan.ReadType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/IsolationLevel.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">IsolationLevel</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">AsyncScanSingleRegionRpcRetryingCaller.ScanControllerState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.client.<a href="../../../../../org/apache/hadoop/hbase/client/RegionLocateType.html" title="enum in org.apache.hadoop.hbase.client"><span class="typeNameLink">RegionLocateType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html b/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
index 1578c9ced30..77729296ff4 100644
--- a/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/coprocessor/package-tree.html
@@ -176,8 +176,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/MetaTableMetrics.MetaTableOps.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">MetaTableMetrics.MetaTableOps</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/RegionObserver.MutationType.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">RegionObserver.MutationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.coprocessor.<a href="../../../../../org/apache/hadoop/hbase/coprocessor/MetaTableMetrics.MetaTableOps.html" title="enum in org.apache.hadoop.hbase.coprocessor"><span class="typeNameLink">MetaTableMetrics.MetaTableOps</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
index a69061f339f..53aaadc16ee 100644
--- a/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/filter/package-tree.html
@@ -190,12 +190,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/BitComparator.BitwiseOp.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">BitComparator.BitwiseOp</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.SatisfiesCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.SatisfiesCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FuzzyRowFilter.Order.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FuzzyRowFilter.Order</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterList.Operator.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterList.Operator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/Filter.ReturnCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">Filter.ReturnCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/RegexStringComparator.EngineType.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">RegexStringComparator.EngineType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.filter.<a href="../../../../../org/apache/hadoop/hbase/filter/FilterWrapper.FilterRowRetCode.html" title="enum in org.apache.hadoop.hbase.filter"><span class="typeNameLink">FilterWrapper.FilterRowRetCode</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html
index 4546fb99bfb..d55e1f3cd8b 100644
--- a/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/hbtop/terminal/package-tree.html
@@ -107,8 +107,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.hbtop.terminal.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/terminal/KeyPress.Type.html" title="enum in org.apache.hadoop.hbase.hbtop.terminal"><span class="typeNameLink">KeyPress.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.hbtop.terminal.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/terminal/Color.html" title="enum in org.apache.hadoop.hbase.hbtop.terminal"><span class="typeNameLink">Color</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.hbtop.terminal.<a href="../../../../../../org/apache/hadoop/hbase/hbtop/terminal/KeyPress.Type.html" title="enum in org.apache.hadoop.hbase.hbtop.terminal"><span class="typeNameLink">KeyPress.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/http/package-tree.html b/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
index f057548c31e..94cdb9e241a 100644
--- a/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/http/package-tree.html
@@ -141,9 +141,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/HttpConfig.Policy.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">HttpConfig.Policy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Event.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Event</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/ProfileServlet.Output.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">ProfileServlet.Output</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.http.<a href="../../../../../org/apache/hadoop/hbase/http/HttpConfig.Policy.html" title="enum in org.apache.hadoop.hbase.http"><span class="typeNameLink">HttpConfig.Policy</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
index 3e51fb61fe7..c6984028cf1 100644
--- a/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/io/hfile/package-tree.html
@@ -320,12 +320,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockCacheFactory.ExternalBlockCaches.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockCacheFactory.ExternalBlockCaches</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/ReaderContext.ReaderType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">ReaderContext.ReaderType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.BlockCategory.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType.BlockCategory</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockType.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/HFileBlock.Writer.State.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">HFileBlock.Writer.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockCacheFactory.ExternalBlockCaches.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockCacheFactory.ExternalBlockCaches</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.io.hfile.<a href="../../../../../../org/apache/hadoop/hbase/io/hfile/BlockPriority.html" title="enum in org.apache.hadoop.hbase.io.hfile"><span class="typeNameLink">BlockPriority</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
index 69c1ab14945..05615d07379 100644
--- a/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/ipc/package-tree.html
@@ -369,8 +369,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/MetricsHBaseServerSourceFactoryImpl.SourceStorage.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">MetricsHBaseServerSourceFactoryImpl.SourceStorage</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/CallEvent.Type.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">CallEvent.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/BufferCallBeforeInitHandler.BufferCallAction.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">BufferCallBeforeInitHandler.BufferCallAction</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.ipc.<a href="../../../../../org/apache/hadoop/hbase/ipc/CallEvent.Type.html" title="enum in org.apache.hadoop.hbase.ipc"><span class="typeNameLink">CallEvent.Type</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
index 846c1cc8c28..3da66164bf8 100644
--- a/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/mapreduce/package-tree.html
@@ -300,11 +300,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/SyncTable.SyncMapper.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">SyncTable.SyncMapper.Counter</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/CellCounter.CellCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">CellCounter.CellCounterMapper.Counters</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/RowCounter.RowCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">RowCounter.RowCounterMapper.Counters</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/WALPlayer.Counter.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">WALPlayer.Counter</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/CellCounter.CellCounterMapper.Counters.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">CellCounter.CellCounterMapper.Counters</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.mapreduce.<a href="../../../../../org/apache/hadoop/hbase/mapreduce/TableSplit.Version.html" title="enum in org.apache.hadoop.hbase.mapreduce"><span class="typeNameLink">TableSplit.Version</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html b/devapidocs/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html
index 38584009feb..44468581c90 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>private class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1146">ServerManager.FlushedSequenceIdFlusher</a>
+<pre>private class <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1151">ServerManager.FlushedSequenceIdFlusher</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/ScheduledChore.html" title="class in org.apache.hadoop.hbase">ScheduledChore</a></pre>
 </li>
 </ul>
@@ -201,7 +201,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/ScheduledChore.html" tit
 <ul class="blockListLast">
 <li class="blockList">
 <h4>FlushedSequenceIdFlusher</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html#line.1148">FlushedSequenceIdFlusher</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;name,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html#line.1153">FlushedSequenceIdFlusher</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;name,
                                 int&nbsp;p)</pre>
 </li>
 </ul>
@@ -219,7 +219,7 @@ extends <a href="../../../../../org/apache/hadoop/hbase/ScheduledChore.html" tit
 <ul class="blockListLast">
 <li class="blockList">
 <h4>chore</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html#line.1153">chore</a>()</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html#line.1158">chore</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/ScheduledChore.html#chore--">ScheduledChore</a></code></span></div>
 <div class="block">The task to execute on each scheduled execution of the Chore</div>
 <dl>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html b/devapidocs/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html
index 9f2cb885ce7..a854d173f42 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html
@@ -122,7 +122,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static enum <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.855">ServerManager.ServerLiveState</a>
+<pre>public static enum <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.860">ServerManager.ServerLiveState</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang">Enum</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a>&gt;</pre>
 </li>
 </ul>
@@ -213,7 +213,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>LIVE</h4>
-<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html#line.856">LIVE</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html#line.861">LIVE</a></pre>
 </li>
 </ul>
 <a name="DEAD">
@@ -222,7 +222,7 @@ the order they are declared.</div>
 <ul class="blockList">
 <li class="blockList">
 <h4>DEAD</h4>
-<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html#line.857">DEAD</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html#line.862">DEAD</a></pre>
 </li>
 </ul>
 <a name="UNKNOWN">
@@ -231,7 +231,7 @@ the order they are declared.</div>
 <ul class="blockListLast">
 <li class="blockList">
 <h4>UNKNOWN</h4>
-<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html#line.858">UNKNOWN</a></pre>
+<pre>public static final&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html#line.863">UNKNOWN</a></pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/ServerManager.html b/devapidocs/org/apache/hadoop/hbase/master/ServerManager.html
index ba54fbfe649..f85ec09844b 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/ServerManager.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/ServerManager.html
@@ -1007,7 +1007,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>updateLastFlushedSequenceIds</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.238">updateLastFlushedSequenceIds</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.243">updateLastFlushedSequenceIds</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn,
                                           <a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&nbsp;hsl)</pre>
 <div class="block">Updates last flushed sequence Ids for the regions on server sn</div>
 </li>
@@ -1018,7 +1018,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>regionServerReport</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.274">regionServerReport</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn,
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.279">regionServerReport</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn,
                                <a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&nbsp;sl)
                         throws <a href="../../../../../org/apache/hadoop/hbase/YouAreDeadException.html" title="class in org.apache.hadoop.hbase">YouAreDeadException</a></pre>
 <dl>
@@ -1033,7 +1033,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>checkAndRecordNewServer</h4>
-<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.298">checkAndRecordNewServer</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.303">checkAndRecordNewServer</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                                 <a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&nbsp;sl)</pre>
 <div class="block">Check is a server of same host and port already exists, if not, or the existed one got a
  smaller start code, record it.</div>
@@ -1052,7 +1052,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>findDeadServersAndProcess</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.340">findDeadServersAndProcess</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;deadServersFromPE,
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.345">findDeadServersAndProcess</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;deadServersFromPE,
                                <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Set.html?is-external=true" title="class or interface in java.util">Set</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;liveServersFromWALDir)</pre>
 <div class="block">Find out the region servers crashed between the crash of the previous master instance and the
  current master instance and schedule SCP for them.
@@ -1076,7 +1076,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>checkClockSkew</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.354">checkClockSkew</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.359">checkClockSkew</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                             long&nbsp;serverCurrentTime)
                      throws <a href="../../../../../org/apache/hadoop/hbase/ClockOutOfSyncException.html" title="class in org.apache.hadoop.hbase">ClockOutOfSyncException</a></pre>
 <div class="block">Checks if the clock skew between the server and the master. If the clock skew exceeds the
@@ -1097,7 +1097,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>checkIsDead</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.378">checkIsDead</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.383">checkIsDead</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                          <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;what)
                   throws <a href="../../../../../org/apache/hadoop/hbase/YouAreDeadException.html" title="class in org.apache.hadoop.hbase">YouAreDeadException</a></pre>
 <div class="block">Called when RegionServer first reports in for duty and thereafter each time it heartbeats to
@@ -1118,7 +1118,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>findServerWithSameHostnamePortWithLock</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.404">findServerWithSameHostnamePortWithLock</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.409">findServerWithSameHostnamePortWithLock</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Assumes onlineServers is locked.</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1132,7 +1132,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>recordNewServerWithLock</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.421">recordNewServerWithLock</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.426">recordNewServerWithLock</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                              <a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&nbsp;sl)</pre>
 <div class="block">Adds the onlineServers list. onlineServers should be locked.</div>
 <dl>
@@ -1147,7 +1147,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getFlushedSequenceIdByRegion</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentNavigableMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentNavigableMap</a>&lt;byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.426">getFlushedSequenceIdByRegion< [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentNavigableMap.html?is-external=true" title="class or interface in java.util.concurrent">ConcurrentNavigableMap</a>&lt;byte[],<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Long.html?is-external=true" title="class or interface in java.lang">Long</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.431">getFlushedSequenceIdByRegion< [...]
 </li>
 </ul>
 <a name="getLastFlushedSequenceId-byte:A-">
@@ -1156,7 +1156,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLastFlushedSequenceId</h4>
-<pre>public&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos.RegionStoreSequenceIds&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.430">getLastFlushedSequenceId</a>(byte[]&nbsp;encodedRegionName)</pre>
+<pre>public&nbsp;org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos.RegionStoreSequenceIds&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.435">getLastFlushedSequenceId</a>(byte[]&nbsp;encodedRegionName)</pre>
 </li>
 </ul>
 <a name="getLoad-org.apache.hadoop.hbase.ServerName-">
@@ -1165,7 +1165,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getLoad</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.449">getLoad</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.454">getLoad</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">n * @return ServerMetrics if serverName is known else null</div>
 </li>
 </ul>
@@ -1175,7 +1175,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getAverageLoad</h4>
-<pre>public&nbsp;double&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.459">getAverageLoad</a>()</pre>
+<pre>public&nbsp;double&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.464">getAverageLoad</a>()</pre>
 <div class="block">Compute the average load across all region servers. Currently, this uses a very naive
  computation - just uses the number of regions being served, ignoring stats about number of
  requests.</div>
@@ -1191,7 +1191,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>countOfRegionServers</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.470">countOfRegionServers</a>()</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.475">countOfRegionServers</a>()</pre>
 <div class="block">Returns the count of active regionservers</div>
 </li>
 </ul>
@@ -1201,7 +1201,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOnlineServers</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManag [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html?is-external=true" title="class or interface in java.util">Map</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>,<a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManag [...]
 <div class="block">Returns Read-only map of servers to serverinfo</div>
 </li>
 </ul>
@@ -1211,7 +1211,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getDeadServers</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/DeadServer.html" title="class in org.apache.hadoop.hbase.master">DeadServer</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.483">getDeadServers</a>()</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/DeadServer.html" title="class in org.apache.hadoop.hbase.master">DeadServer</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.488">getDeadServers</a>()</pre>
 </li>
 </ul>
 <a name="areDeadServersInProgress--">
@@ -1220,7 +1220,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>areDeadServersInProgress</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.491">areDeadServersInProgress</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.496">areDeadServersInProgress</a>()
                                  throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Checks if any dead servers are currently in progress.</div>
 <dl>
@@ -1237,7 +1237,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>letRegionServersShutdown</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.496">letRegionServersShutdown</a>()</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.501">letRegionServersShutdown</a>()</pre>
 </li>
 </ul>
 <a name="getRegionServersInZK-org.apache.hadoop.hbase.zookeeper.ZKWatcher-">
@@ -1246,7 +1246,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionServersInZK</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.547">getRegionServersInZK</a>(<a href="../../../../../org/apache/hadoop/hbase/zookeeper/ZKWatc [...]
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.552">getRegionServersInZK</a>(<a href="../../../../../org/apache/hadoop/hbase/zookeeper/ZKWatc [...]
                                    throws org.apache.zookeeper.KeeperException</pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1260,7 +1260,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>expireServer</h4>
-<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.559">expireServer</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.564">expireServer</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Expire the passed server. Add it to list of dead servers and queue a shutdown processing.</div>
 <dl>
 <dt><span class="returnLabel">Returns:</span></dt>
@@ -1277,7 +1277,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>expireServer</h4>
-<pre>long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.564">expireServer</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
+<pre>long&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.569">expireServer</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName,
                   boolean&nbsp;force)</pre>
 </li>
 </ul>
@@ -1287,7 +1287,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>moveFromOnlineToDeadServers</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.619">moveFromOnlineToDeadServers</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.624">moveFromOnlineToDeadServers</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn)</pre>
 <div class="block">Called when server has expired.</div>
 </li>
 </ul>
@@ -1297,7 +1297,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeServerFromDrainList</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.641">removeServerFromDrainList</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.646">removeServerFromDrainList</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn)</pre>
 </li>
 </ul>
 <a name="addServerToDrainList-org.apache.hadoop.hbase.ServerName-">
@@ -1306,7 +1306,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>addServerToDrainList</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.657">addServerToDrainList</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.662">addServerToDrainList</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;sn)</pre>
 <div class="block">Add the server to the drain list. n * @return True if the server is added or the server is
  already on the drain list.</div>
 </li>
@@ -1317,7 +1317,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>closeRegionSilentlyAndWait</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.681">closeRegionSilentlyAndWait</a>(<a href="../../../../../org/apache/hadoop/hbase/client/AsyncClusterConnection.html" title="interface in org.apache.hadoop.hbase.client">AsyncClusterConnection</a>&nbsp;connection,
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.686">closeRegionSilentlyAndWait</a>(<a href="../../../../../org/apache/hadoop/hbase/client/AsyncClusterConnection.html" title="interface in org.apache.hadoop.hbase.client">AsyncClusterConnection</a>&nbsp;connection,
                                               <a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server,
                                               <a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;region,
                                               long&nbsp;timeout)
@@ -1338,7 +1338,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getMinToStart</h4>
-<pre>private&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.724">getMinToStart</a>()</pre>
+<pre>private&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.729">getMinToStart</a>()</pre>
 <div class="block">Calculate min necessary to start. This is not an absolute. It is just a friction that will
  cause us hang around a bit longer waiting on RegionServers to check-in.</div>
 </li>
@@ -1349,7 +1349,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>waitForRegionServers</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.744">waitForRegionServers</a>(<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.html" title="interface in org.apache.hadoop.hbase.monitoring">MonitoredTask</a>&nbsp;status)
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.749">waitForRegionServers</a>(<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.html" title="interface in org.apache.hadoop.hbase.monitoring">MonitoredTask</a>&nbsp;status)
                           throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a></pre>
 <div class="block">Wait for the region servers to report in. We will wait until one of this condition is met: -
  the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region
@@ -1368,7 +1368,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getStrForMax</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.814">getStrForMax</a>(int&nbsp;max)</pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.819">getStrForMax</a>(int&nbsp;max)</pre>
 </li>
 </ul>
 <a name="getOnlineServersList--">
@@ -1377,7 +1377,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOnlineServersList</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.819">getOnlineServersList</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.824">getOnlineServersList</a>()</pre>
 <div class="block">Returns A copy of the internal list of online servers.</div>
 </li>
 </ul>
@@ -1387,7 +1387,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getOnlineServersListWithPredicator</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.830">getOnlineServersListWithPredicator</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?i [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.835">getOnlineServersListWithPredicator</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?i [...]
                                                            <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html?is-external=true" title="class or interface in java.util.function">Predicate</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerMetrics.html" title="interface in org.apache.hadoop.hbase">ServerMetrics</a>&gt;&nbsp;idleServerPredicator)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1404,7 +1404,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getDrainingServersList</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.847">getDrainingServersList</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.852">getDrainingServersList</a>()</pre>
 <div class="block">Returns A copy of the internal list of draining servers.</div>
 </li>
 </ul>
@@ -1414,7 +1414,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isServerOnline</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.851">isServerOnline</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.856">isServerOnline</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 </li>
 </ul>
 <a name="isServerKnownAndOnline-org.apache.hadoop.hbase.ServerName-">
@@ -1423,7 +1423,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isServerKnownAndOnline</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.862">isServerKnownAndOnline</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master">ServerManager.ServerLiveState</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.867">isServerKnownAndOnline</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Returns whether the server is online, dead, or unknown.</div>
 </li>
 </ul>
@@ -1433,7 +1433,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isServerDead</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.873">isServerDead</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.878">isServerDead</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Check if a server is known to be dead. A server can be online, or known to be dead, or unknown
  to this manager (i.e, not online, not known to be dead either; it is simply not tracked by the
  master any more, for example, a very old previous instance).</div>
@@ -1445,7 +1445,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isServerUnknown</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.882">isServerUnknown</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.887">isServerUnknown</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">Check if a server is unknown. A server can be online, or known to be dead, or unknown to this
  manager (i.e, not online, not known to be dead either; it is simply not tracked by the master
  any more, for example, a very old previous instance).</div>
@@ -1457,7 +1457,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>shutdownCluster</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.887">shutdownCluster</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.892">shutdownCluster</a>()</pre>
 </li>
 </ul>
 <a name="isClusterShutdown--">
@@ -1466,7 +1466,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isClusterShutdown</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.897">isClusterShutdown</a>()</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.902">isClusterShutdown</a>()</pre>
 </li>
 </ul>
 <a name="startChore--">
@@ -1475,7 +1475,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>startChore</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.904">startChore</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.909">startChore</a>()</pre>
 <div class="block">start chore in ServerManager</div>
 </li>
 </ul>
@@ -1485,7 +1485,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>stop</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.924">stop</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.929">stop</a>()</pre>
 <div class="block">Stop the ServerManager.</div>
 </li>
 </ul>
@@ -1495,7 +1495,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>createDestinationServersList</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.942">createDestinationServersList</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-exte [...]
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.947">createDestinationServersList</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-exte [...]
 <div class="block">Creates a list of possible destinations for a region. It contains the online servers, but not
  the draining or dying servers.</div>
 <dl>
@@ -1510,7 +1510,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>createDestinationServersList</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.967">createDestinationServersList</a>()</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.972">createDestinationServersList</a>()</pre>
 <div class="block">Calls <a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.html#createDestinationServersList-java.util.List-"><code>createDestinationServersList(java.util.List&lt;org.apache.hadoop.hbase.ServerName&gt;)</code></a> without server to exclude.</div>
 </li>
 </ul>
@@ -1520,7 +1520,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>clearDeadServersWithSameHostNameAndPortOfOnlineServer</h4>
-<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.974">clearDeadServersWithSameHostNameAndPortOfOnlineServer</a>()</pre>
+<pre>void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.979">clearDeadServersWithSameHostNameAndPortOfOnlineServer</a>()</pre>
 <div class="block">To clear any dead server with same host name and port of any online server</div>
 </li>
 </ul>
@@ -1530,7 +1530,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRegion</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.983">removeRegion</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.988">removeRegion</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;regionInfo)</pre>
 <div class="block">Called by delete table and similar to notify the ServerManager that a region was removed.</div>
 </li>
 </ul>
@@ -1540,7 +1540,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>isRegionInServerManagerStates</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.989">isRegionInServerManagerStates</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</pre>
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.994">isRegionInServerManagerStates</a>(<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&nbsp;hri)</pre>
 </li>
 </ul>
 <a name="removeRegions-java.util.List-">
@@ -1549,7 +1549,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>removeRegions</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.998">removeRegions</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;regions)</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1003">removeRegions</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;regions)</pre>
 <div class="block">Called by delete table and similar to notify the ServerManager that a region was removed.</div>
 </li>
 </ul>
@@ -1559,7 +1559,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getVersionNumber</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1007">getVersionNumber</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1012">getVersionNumber</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">May return 0 when server is not online.</div>
 </li>
 </ul>
@@ -1569,7 +1569,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getVersion</h4>
-<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1015">getVersion</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1020">getVersion</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 <div class="block">May return "0.0.0" when server is not online</div>
 </li>
 </ul>
@@ -1579,7 +1579,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>getInfoPort</h4>
-<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1020">getInfoPort</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
+<pre>public&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1025">getInfoPort</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;serverName)</pre>
 </li>
 </ul>
 <a name="persistRegionLastFlushedSequenceIds--">
@@ -1588,7 +1588,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>persistRegionLastFlushedSequenceIds</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1029">persistRegionLastFlushedSequenceIds</a>()
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1034">persistRegionLastFlushedSequenceIds</a>()
                                           throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Persist last flushed sequence id of each region to HDFS</div>
 <dl>
@@ -1603,7 +1603,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>loadLastFlushedSequenceIds</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1082">loadLastFlushedSequenceIds</a>()
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1087">loadLastFlushedSequenceIds</a>()
                                 throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Load last flushed sequence id of each region from HDFS, if persisted</div>
 <dl>
@@ -1618,7 +1618,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockListLast">
 <li class="blockList">
 <h4>removeDeletedRegionFromLoadedFlushedSequenceIds</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1134">removeDeletedRegionFromLoadedFlushedSequenceIds</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/master/ServerManager.html#line.1139">removeDeletedRegionFromLoadedFlushedSequenceIds</a>()</pre>
 <div class="block">Regions may have been removed between latest persist of FlushedSequenceIds and master abort. So
  after loading FlushedSequenceIds from file, and after meta loaded, we need to remove the
  deleted region according to RegionStates.</div>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
index 475086d6fc4..b080f222931 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/balancer/package-tree.html
@@ -212,8 +212,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.GeneratorType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">StochasticLoadBalancer.GeneratorType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalanceAction.Type.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalanceAction.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.GeneratorType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">StochasticLoadBalancer.GeneratorType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.balancer.<a href="../../../../../../org/apache/hadoop/hbase/master/balancer/BalancerClusterState.LocalityType.html" title="enum in org.apache.hadoop.hbase.master.balancer"><span class="typeNameLink">BalancerClusterState.LocalityType</span></a></li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
index 5f3bc26a259..0d70a9f26be 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/package-tree.html
@@ -318,12 +318,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">RegionState.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MetricsMasterSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MetricsMasterSourceFactoryImpl.FactoryStorage</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.ResubmitDirective.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.ResubmitDirective</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">ServerManager.ServerLiveState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/MasterRpcServices.BalanceSwitchMode.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">MasterRpcServices.BalanceSwitchMode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/SplitLogManager.TerminationStatus.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">SplitLogManager.TerminationStatus</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.<a href="../../../../../org/apache/hadoop/hbase/master/RegionState.State.html" title="enum in org.apache.hadoop.hbase.master"><span class="typeNameLink">RegionState.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
index f70281ee573..4d5ee070a62 100644
--- a/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/master/procedure/package-tree.html
@@ -226,10 +226,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MetaProcedureInterface.MetaOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">MetaProcedureInterface.MetaOperationType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/ServerProcedureInterface.ServerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">ServerProcedureInterface.ServerOperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/TableProcedureInterface.TableOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">TableProcedureInterface.TableOperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/ServerProcedureInterface.ServerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">ServerProcedureInterface.ServerOperationType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/PeerProcedureInterface.PeerOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">PeerProcedureInterface.PeerOperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.master.procedure.<a href="../../../../../../org/apache/hadoop/hbase/master/procedure/MetaProcedureInterface.MetaOperationType.html" title="enum in org.apache.hadoop.hbase.master.procedure"><span class="typeNameLink">MetaProcedureInterface.MetaOperationType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
index feb8a8c188c..ea16cfa6271 100644
--- a/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/monitoring/package-tree.html
@@ -126,8 +126,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/TaskMonitor.TaskFilter.TaskType.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">TaskMonitor.TaskFilter.TaskType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.monitoring.<a href="../../../../../org/apache/hadoop/hbase/monitoring/MonitoredTask.State.html" title="enum in org.apache.hadoop.hbase.monitoring"><span class="typeNameLink">MonitoredTask.State</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/package-tree.html b/devapidocs/org/apache/hadoop/hbase/package-tree.html
index 3eb2dc5617c..f84659f714d 100644
--- a/devapidocs/org/apache/hadoop/hbase/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/package-tree.html
@@ -483,22 +483,22 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ServerTask.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ServerTask.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClientMetaTableAccessor.QueryType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClientMetaTableAccessor.QueryType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HConstants.OperationStatusCode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HConstants.OperationStatusCode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HealthChecker.HealthCheckerExitStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeepDeletedCells.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeepDeletedCells</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterMetrics.Option</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CellBuilderType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CellBuilderType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompatibilitySingletonFactory.SingletonStorage.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompatibilitySingletonFactory.SingletonStorage</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HConstants.OperationStatusCode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HConstants.OperationStatusCode</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ServerTask.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ServerTask.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Size.Unit.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Size.Unit</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CompareOperator.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CompareOperator</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Cell.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Cell.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MetaRegionLocationCache.ZNodeOpType.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MetaRegionLocationCache.ZNodeOpType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/KeyValue.Type.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">KeyValue.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/MemoryCompactionPolicy.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">MemoryCompactionPolicy</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/CatalogReplicaMode.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">CatalogReplicaMode</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/HealthChecker.HealthCheckerExitStatus.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">HealthChecker.HealthCheckerExitStatus</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/Coprocessor.State.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">Coprocessor.State</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.<a href="../../../../org/apache/hadoop/hbase/ClusterMetrics.Option.html" title="enum in org.apache.hadoop.hbase"><span class="typeNameLink">ClusterMetrics.Option</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
index f82d01b578a..fd20de58b1f 100644
--- a/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/procedure2/package-tree.html
@@ -217,11 +217,11 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">RootProcedureState.State</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/Procedure.LockState.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">Procedure.LockState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/RootProcedureState.State.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">RootProcedureState.State</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/StateMachineProcedure.Flow.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">StateMachineProcedure.Flow</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockedResourceType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockedResourceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.procedure2.<a href="../../../../../org/apache/hadoop/hbase/procedure2/LockType.html" title="enum in org.apache.hadoop.hbase.procedure2"><span class="typeNameLink">LockType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
index 60f3e3f54c6..9a068ac1e1e 100644
--- a/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/quotas/package-tree.html
@@ -242,10 +242,10 @@
 <ul>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/ThrottleType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">ThrottleType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/RpcThrottlingException.Type.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">RpcThrottlingException.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaScope.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaScope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/OperationQuota.OperationType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">OperationQuota.OperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/SpaceViolationPolicy.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">SpaceViolationPolicy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.quotas.<a href="../../../../../org/apache/hadoop/hbase/quotas/QuotaType.html" title="enum in org.apache.hadoop.hbase.quotas"><span class="typeNameLink">QuotaType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
index 89c4ff05ad2..13da937ed0d 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/package-tree.html
@@ -754,18 +754,18 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/FlushType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">FlushType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/SplitLogWorker.TaskExecutor.Status.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">SplitLogWorker.TaskExecutor.Status</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MetricsRegionServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MetricsRegionServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/MemStoreCompactionStrategy.Action.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">MemStoreCompactionStrategy.Action</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScanType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScanType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.NextState.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.NextState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/FlushType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">FlushType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/Region.Operation.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">Region.Operation</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/CompactingMemStore.IndexType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">CompactingMemStore.IndexType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/DefaultHeapMemoryTuner.StepDirection.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">DefaultHeapMemoryTuner.StepDirection</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/HRegion.FlushResult.Result.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">HRegion.FlushResult.Result</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ChunkCreator.ChunkType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ChunkCreator.ChunkType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/TimeRangeTracker.Type.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">TimeRangeTracker.Type</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/BloomType.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">BloomType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.<a href="../../../../../org/apache/hadoop/hbase/regionserver/ScannerContext.LimitScope.html" title="enum in org.apache.hadoop.hbase.regionserver"><span class="typeNameLink">ScannerContext.LimitScope</span></a></li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
index e429447de7c..7a8ed9de901 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/querymatcher/package-tree.html
@@ -130,9 +130,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/StripeCompactionScanQueryMatcher.DropDeletesInOutput.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">StripeCompactionScanQueryMatcher.DropDeletesInOutput</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/ScanQueryMatcher.MatchCode.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">ScanQueryMatcher.MatchCode</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/DeleteTracker.DeleteResult.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">DeleteTracker.DeleteResult</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.querymatcher.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/querymatcher/StripeCompactionScanQueryMatcher.DropDeletesInOutput.html" title="enum in org.apache.hadoop.hbase.regionserver.querymatcher"><span class="typeNameLink">StripeCompactionScanQueryMatcher.DropDeletesInOutput</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
index 793f3a90fd6..cfe3ebe1c36 100644
--- a/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/regionserver/wal/package-tree.html
@@ -250,10 +250,10 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/CompressionContext.DictionaryIndex.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">CompressionContext.DictionaryIndex</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">ProtobufLogReader.WALHdrResult</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/WALActionsListener.RollRequestReason.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">WALActionsListener.RollRequestReason</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/RingBufferTruck.Type.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">RingBufferTruck.Type</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/CompressionContext.DictionaryIndex.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">CompressionContext.DictionaryIndex</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.regionserver.wal.<a href="../../../../../../org/apache/hadoop/hbase/regionserver/wal/ProtobufLogReader.WALHdrResult.html" title="enum in org.apache.hadoop.hbase.regionserver.wal"><span class="typeNameLink">ProtobufLogReader.WALHdrResult</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html b/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
index f9442ed52e7..13f95f813bf 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/package-tree.html
@@ -173,8 +173,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/ReplicationPeer.PeerState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">ReplicationPeer.PeerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/SyncReplicationState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">SyncReplicationState</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.replication.<a href="../../../../../org/apache/hadoop/hbase/replication/ReplicationPeer.PeerState.html" title="enum in org.apache.hadoop.hbase.replication"><span class="typeNameLink">ReplicationPeer.PeerState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
index 403410bfd67..d593a90b71f 100644
--- a/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/replication/regionserver/package-tree.html
@@ -216,8 +216,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceShipper.WorkerState.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">ReplicationSourceShipper.WorkerState</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/MetricsReplicationSourceFactoryImpl.SourceHolder.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">MetricsReplicationSourceFactoryImpl.SourceHolder</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.replication.regionserver.<a href="../../../../../../org/apache/hadoop/hbase/replication/regionserver/ReplicationSourceShipper.WorkerState.html" title="enum in org.apache.hadoop.hbase.replication.regionserver"><span class="typeNameLink">ReplicationSourceShipper.WorkerState</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html b/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
index 08844c3ed86..4759df08a3f 100644
--- a/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/rest/model/package-tree.html
@@ -110,8 +110,8 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.rest.model.<a href="../../../../../../org/apache/hadoop/hbase/rest/model/ScannerModel.FilterModel.FilterType.html" title="enum in org.apache.hadoop.hbase.rest.model"><span class="typeNameLink">ScannerModel.FilterModel.FilterType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.rest.model.<a href="../../../../../../org/apache/hadoop/hbase/rest/model/ScannerModel.FilterModel.ByteArrayComparableModel.ComparatorType.html" title="enum in org.apache.hadoop.hbase.rest.model"><span class="typeNameLink">ScannerModel.FilterModel.ByteArrayComparableModel.ComparatorType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.rest.model.<a href="../../../../../../org/apache/hadoop/hbase/rest/model/ScannerModel.FilterModel.FilterType.html" title="enum in org.apache.hadoop.hbase.rest.model"><span class="typeNameLink">ScannerModel.FilterModel.FilterType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
index bb291cc956e..c59a9a17e51 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/access/package-tree.html
@@ -162,12 +162,12 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessControlFilter.Strategy.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessControlFilter.Strategy</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Action.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Action</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/AccessController.OpType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">AccessController.OpType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/Permission.Scope.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">Permission.Scope</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.AclType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.access.<a href="../../../../../../org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType.html" title="enum in org.apache.hadoop.hbase.security.access"><span class="typeNameLink">SnapshotScannerHDFSAclHelper.HDFSAclOperation.OperationType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
index 307514f53ee..444e8d5cefe 100644
--- a/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/security/package-tree.html
@@ -196,9 +196,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslUtil.QualityOfProtection.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslUtil.QualityOfProtection</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/AuthMethod.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">AuthMethod</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslStatus.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslStatus</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.security.<a href="../../../../../org/apache/hadoop/hbase/security/SaslUtil.QualityOfProtection.html" title="enum in org.apache.hadoop.hbase.security"><span class="typeNameLink">SaslUtil.QualityOfProtection</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
index be1df7e35a6..e36d11617c2 100644
--- a/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/thrift/package-tree.html
@@ -211,9 +211,9 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
+<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftMetrics.ThriftServerType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftMetrics.ThriftServerType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/MetricsThriftServerSourceFactoryImpl.FactoryStorage.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">MetricsThriftServerSourceFactoryImpl.FactoryStorage</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ImplType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ImplType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.thrift.<a href="../../../../../org/apache/hadoop/hbase/thrift/ThriftMetrics.ThriftServerType.html" title="enum in org.apache.hadoop.hbase.thrift"><span class="typeNameLink">ThriftMetrics.ThriftServerType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html b/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html
index 6566d6c7162..a0bda005501 100644
--- a/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/trace/package-tree.html
@@ -98,8 +98,8 @@
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
 <li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.ReadType.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.ReadType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.Operation.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.Operation</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.RpcSystem.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.RpcSystem</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.trace.<a href="../../../../../org/apache/hadoop/hbase/trace/HBaseSemanticAttributes.Operation.html" title="enum in org.apache.hadoop.hbase.trace"><span class="typeNameLink">HBaseSemanticAttributes.Operation</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html b/devapidocs/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html
index 5adec1ec6fd..2b7baf7e2aa 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html
@@ -113,7 +113,7 @@ var activeTableTab = "activeTableTab";
 </dl>
 <hr>
 <br>
-<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.142">RegionMover.RegionMoverBuilder</a>
+<pre>public static class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.155">RegionMover.RegionMoverBuilder</a>
 extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html?is-external=true" title="class or interface in java.lang">Object</a></pre>
 <div class="block">Builder for Region mover. Use the <a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#build--"><code>build()</code></a> method to create RegionMover object. Has
  <a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#filename-java.lang.String-"><code>filename(String)</code></a>, <a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#excludeFile-java.lang.String-"><code>excludeFile(String)</code></a>, <a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#maxthreads-int-"><code>maxthreads(int)</code></a>,
@@ -303,7 +303,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>ack</h4>
-<pre>private&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.143">ack</a></pre>
+<pre>private&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.156">ack</a></pre>
 </li>
 </ul>
 <a name="maxthreads">
@@ -312,7 +312,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>maxthreads</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.144">maxthreads</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.157">maxthreads</a></pre>
 </li>
 </ul>
 <a name="timeout">
@@ -321,7 +321,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>timeout</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.145">timeout</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.158">timeout</a></pre>
 </li>
 </ul>
 <a name="hostname">
@@ -330,7 +330,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>hostname</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.146">hostname</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.159">hostname</a></pre>
 </li>
 </ul>
 <a name="filename">
@@ -339,7 +339,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>filename</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.147">filename</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.160">filename</a></pre>
 </li>
 </ul>
 <a name="excludeFile">
@@ -348,7 +348,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>excludeFile</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.148">excludeFile</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.161">excludeFile</a></pre>
 </li>
 </ul>
 <a name="designatedFile">
@@ -357,7 +357,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>designatedFile</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.149">designatedFile</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.162">designatedFile</a></pre>
 </li>
 </ul>
 <a name="defaultDir">
@@ -366,7 +366,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <ul class="blockList">
 <li class="blockList">
 <h4>defaultDir</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.150">defaultDir</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.163">defaultDir</a></pre>
 </li>
 </ul>
 <a name="port">
@@ -376,7 +376,7 @@ extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
 <li class="blockList">
 <h4>port</h4>
 <pre>@InterfaceAudience.Private
-final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.152">port</a></pre>
+final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.165">port</a></pre>
 </li>
 </ul>
 <a name="conf">
@@ -385,7 +385,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>conf</h4>
-<pre>private final&nbsp;org.apache.hadoop.conf.Configuration <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.153">conf</a></pre>
+<pre>private final&nbsp;org.apache.hadoop.conf.Configuration <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.166">conf</a></pre>
 </li>
 </ul>
 <a name="rackManager">
@@ -394,7 +394,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockListLast">
 <li class="blockList">
 <h4>rackManager</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.154">rackManager</a></pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.167">rackManager</a></pre>
 </li>
 </ul>
 </li>
@@ -411,7 +411,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>RegionMoverBuilder</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.156">RegionMoverBuilder</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;hostname)</pre>
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.169">RegionMoverBuilder</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;hostname)</pre>
 </li>
 </ul>
 <a name="RegionMoverBuilder-java.lang.String-org.apache.hadoop.conf.Configuration-">
@@ -420,7 +420,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionMoverBuilder</h4>
-<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.176">RegionMoverBuilder</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;hostname,
+<pre>public&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.189">RegionMoverBuilder</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;hostname,
                           org.apache.hadoop.conf.Configuration&nbsp;conf)</pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -444,7 +444,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>createConf</h4>
-<pre>private static&nbsp;org.apache.hadoop.conf.Configuration&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.163">createConf</a>()</pre>
+<pre>private static&nbsp;org.apache.hadoop.conf.Configuration&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.176">createConf</a>()</pre>
 <div class="block">Creates a new configuration and sets region mover specific overrides</div>
 </li>
 </ul>
@@ -454,7 +454,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>filename</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.193">filename</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;filename)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.206">filename</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;filename)</pre>
 <div class="block">Path of file where regions will be written to during unloading/read from during loading n
  * @return RegionMoverBuilder object</div>
 </li>
@@ -465,7 +465,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>maxthreads</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.201">maxthreads</a>(int&nbsp;threads)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.214">maxthreads</a>(int&nbsp;threads)</pre>
 <div class="block">Set the max number of threads that will be used to move regions</div>
 </li>
 </ul>
@@ -475,7 +475,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>excludeFile</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.211">excludeFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;excludefile)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.224">excludeFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;excludefile)</pre>
 <div class="block">Path of file containing hostnames to be excluded during region movement. Exclude file should
  have 'host:port' per line. Port is mandatory here as we can have many RS running on a single
  host.</div>
@@ -487,7 +487,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>designatedFile</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.223">designatedFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;designatedFile)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.236">designatedFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;designatedFile)</pre>
 <div class="block">Set the designated file. Designated file contains hostnames where region moves. Designated
  file should have 'host:port' per line. Port is mandatory here as we can have many RS running
  on a single host.</div>
@@ -505,7 +505,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>ack</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.238">ack</a>(boolean&nbsp;ack)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.251">ack</a>(boolean&nbsp;ack)</pre>
 <div class="block">Set ack/noAck mode.
  <p>
  In ack mode regions are acknowledged before and after moving and the move is retried
@@ -522,7 +522,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <ul class="blockList">
 <li class="blockList">
 <h4>timeout</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.250">timeout</a>(int&nbsp;timeout)</pre>
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.263">timeout</a>(int&nbsp;timeout)</pre>
 <div class="block">Set the timeout for Load/Unload operation in seconds.This is a global timeout,threadpool for
  movers also have a separate time which is hbase.move.wait.max * number of regions to
  load/unload</div>
@@ -541,7 +541,7 @@ final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/Reg
 <li class="blockList">
 <h4>rackManager</h4>
 <pre>@InterfaceAudience.Private
-public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.261">rackManager</a>(<a href="../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a>&nbsp;rackManager)</pre>
+public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.274">rackManager</a>(<a href="../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a>&nbsp;rackManager)</pre>
 <div class="block">Set specific rackManager implementation. This setter method is for testing purpose only.</div>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -557,7 +557,7 @@ public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.Reg
 <ul class="blockListLast">
 <li class="blockList">
 <h4>build</h4>
-<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.html" title="class in org.apache.hadoop.hbase.util">RegionMover</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.271">build</a>()
+<pre>public&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.html" title="class in org.apache.hadoop.hbase.util">RegionMover</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html#line.284">build</a>()
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">This method builds the appropriate RegionMover object which can then be used to load/unload
  using load and unload methods</div>
diff --git a/devapidocs/org/apache/hadoop/hbase/util/RegionMover.html b/devapidocs/org/apache/hadoop/hbase/util/RegionMover.html
index d57ff518790..a202c6cbb25 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/RegionMover.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/RegionMover.html
@@ -119,7 +119,7 @@ var activeTableTab = "activeTableTab";
 <hr>
 <br>
 <pre>@InterfaceAudience.Public
-public class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.83">RegionMover</a>
+public class <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.85">RegionMover</a>
 extends <a href="../../../../../org/apache/hadoop/hbase/util/AbstractHBaseTool.html" title="class in org.apache.hadoop.hbase.util">AbstractHBaseTool</a>
 implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</a></pre>
 <div class="block">Tool for loading/unloading regions to/from given regionserver This tool can be run from Command
@@ -491,7 +491,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>MOVE_RETRIES_MAX_KEY</h4>
-<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.84">MOVE_RETRIES_MAX_KEY</a></pre>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.86">MOVE_RETRIES_MAX_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.MOVE_RETRIES_MAX_KEY">Constant Field Values</a></dd>
@@ -504,7 +504,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>MOVE_WAIT_MAX_KEY</h4>
-<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.85">MOVE_WAIT_MAX_KEY</a></pre>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.87">MOVE_WAIT_MAX_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.MOVE_WAIT_MAX_KEY">Constant Field Values</a></dd>
@@ -517,7 +517,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>SERVERSTART_WAIT_MAX_KEY</h4>
-<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.86">SERVERSTART_WAIT_MAX_KEY</a></pre>
+<pre>public static final&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.88">SERVERSTART_WAIT_MAX_KEY</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.SERVERSTART_WAIT_MAX_KEY">Constant Field Values</a></dd>
@@ -530,7 +530,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MOVE_RETRIES_MAX</h4>
-<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.87">DEFAULT_MOVE_RETRIES_MAX</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.89">DEFAULT_MOVE_RETRIES_MAX</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.DEFAULT_MOVE_RETRIES_MAX">Constant Field Values</a></dd>
@@ -543,7 +543,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_MOVE_WAIT_MAX</h4>
-<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.88">DEFAULT_MOVE_WAIT_MAX</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.90">DEFAULT_MOVE_WAIT_MAX</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.DEFAULT_MOVE_WAIT_MAX">Constant Field Values</a></dd>
@@ -556,7 +556,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>DEFAULT_SERVERSTART_WAIT_MAX</h4>
-<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.89">DEFAULT_SERVERSTART_WAIT_MAX</a></pre>
+<pre>public static final&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.91">DEFAULT_SERVERSTART_WAIT_MAX</a></pre>
 <dl>
 <dt><span class="seeLabel">See Also:</span></dt>
 <dd><a href="../../../../../constant-values.html#org.apache.hadoop.hbase.util.RegionMover.DEFAULT_SERVERSTART_WAIT_MAX">Constant Field Values</a></dd>
@@ -569,7 +569,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>LOG</h4>
-<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.91">LOG</a></pre>
+<pre>private static final&nbsp;org.slf4j.Logger <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.93">LOG</a></pre>
 </li>
 </ul>
 <a name="rmbuilder">
@@ -578,7 +578,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>rmbuilder</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.93">rmbuilder</a></pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.95">rmbuilder</a></pre>
 </li>
 </ul>
 <a name="ack">
@@ -587,7 +587,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>ack</h4>
-<pre>private&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.94">ack</a></pre>
+<pre>private&nbsp;boolean <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.96">ack</a></pre>
 </li>
 </ul>
 <a name="maxthreads">
@@ -596,7 +596,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>maxthreads</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.95">maxthreads</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.97">maxthreads</a></pre>
 </li>
 </ul>
 <a name="timeout">
@@ -605,7 +605,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>timeout</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.96">timeout</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.98">timeout</a></pre>
 </li>
 </ul>
 <a name="loadUnload">
@@ -614,7 +614,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>loadUnload</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.97">loadUnload</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.99">loadUnload</a></pre>
 </li>
 </ul>
 <a name="hostname">
@@ -623,7 +623,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>hostname</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.98">hostname</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.100">hostname</a></pre>
 </li>
 </ul>
 <a name="filename">
@@ -632,7 +632,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>filename</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.99">filename</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.101">filename</a></pre>
 </li>
 </ul>
 <a name="excludeFile">
@@ -641,7 +641,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>excludeFile</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.100">excludeFile</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.102">excludeFile</a></pre>
 </li>
 </ul>
 <a name="designatedFile">
@@ -650,7 +650,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>designatedFile</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.101">designatedFile</a></pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.103">designatedFile</a></pre>
 </li>
 </ul>
 <a name="port">
@@ -659,7 +659,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>port</h4>
-<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.102">port</a></pre>
+<pre>private&nbsp;int <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.104">port</a></pre>
 </li>
 </ul>
 <a name="conn">
@@ -668,7 +668,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>conn</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/Connection.html" title="interface in org.apache.hadoop.hbase.client">Connection</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.103">conn</a></pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/Connection.html" title="interface in org.apache.hadoop.hbase.client">Connection</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.105">conn</a></pre>
 </li>
 </ul>
 <a name="admin">
@@ -677,7 +677,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>admin</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/Admin.html" title="interface in org.apache.hadoop.hbase.client">Admin</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.104">admin</a></pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/client/Admin.html" title="interface in org.apache.hadoop.hbase.client">Admin</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.106">admin</a></pre>
 </li>
 </ul>
 <a name="rackManager">
@@ -686,7 +686,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockListLast">
 <li class="blockList">
 <h4>rackManager</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.105">rackManager</a></pre>
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/master/RackManager.html" title="class in org.apache.hadoop.hbase.master">RackManager</a> <a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.107">rackManager</a></pre>
 </li>
 </ul>
 </li>
@@ -703,7 +703,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>RegionMover</h4>
-<pre>private&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.107">RegionMover</a>(<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;builder)
+<pre>private&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.109">RegionMover</a>(<a href="../../../../../org/apache/hadoop/hbase/util/RegionMover.RegionMoverBuilder.html" title="class in org.apache.hadoop.hbase.util">RegionMover.RegionMoverBuilder</a>&nbsp;builder)
              throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -717,7 +717,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockListLast">
 <li class="blockList">
 <h4>RegionMover</h4>
-<pre>private&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.127">RegionMover</a>()</pre>
+<pre>private&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.140">RegionMover</a>()</pre>
 </li>
 </ul>
 </li>
@@ -734,7 +734,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>close</h4>
-<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.131">close</a>()</pre>
+<pre>public&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.144">close</a>()</pre>
 <dl>
 <dt><span class="overrideSpecifyLabel">Specified by:</span></dt>
 <dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html?is-external=true#close--" title="class or interface in java.io">close</a></code>&nbsp;in interface&nbsp;<code><a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html?is-external=true" title="class or interface in java.io">Closeable</a></code></dd>
@@ -749,7 +749,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>load</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.281">load</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.294">load</a>()
              throws <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                     <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                     <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -771,7 +771,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>getMetaRegionMovePlan</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.293">getMetaRegionMovePlan</a>()</pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.306">getMetaRegionMovePlan</a>()</pre>
 </li>
 </ul>
 <a name="getNonMetaRegionsMovePlan--">
@@ -780,7 +780,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>getNonMetaRegionsMovePlan</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.297">getNonMetaRegionsMovePlan</a>()</pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.310">getNonMetaRegionsMovePlan</a>()</pre>
 </li>
 </ul>
 <a name="getRegionsMovePlan-boolean-">
@@ -789,7 +789,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>getRegionsMovePlan</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.301">getRegionsMovePlan</a>(boolean&nbsp;moveMetaRegion)</pre>
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html?is-external=true" title="class or interface in java.util.concurrent">Callable</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.314">getRegionsMovePlan</a>(boolean&nbsp;moveMetaRegion)</pre>
 </li>
 </ul>
 <a name="getMetaRegionInfoIfToBeMoved-java.util.List-">
@@ -798,7 +798,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>getMetaRegionInfoIfToBeMoved</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html?is-external=true" title="class or interface in java.util">Optional</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.326">getMetaRegionInfoIfToBeMoved</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java [...]
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html?is-external=true" title="class or interface in java.util">Optional</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.339">getMetaRegionInfoIfToBeMoved</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java [...]
 </li>
 </ul>
 <a name="loadRegions-java.util.List-">
@@ -807,7 +807,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>loadRegions</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.330">loadRegions</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;regionsToMove)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.343">loadRegions</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;regionsToMove)
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -821,7 +821,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>unload</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.379">unload</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.392">unload</a>()
                throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                       <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                       <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -846,7 +846,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>unloadFromRack</h4>
-<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.393">unloadFromRack</a>()
+<pre>public&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.406">unloadFromRack</a>()
                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -873,7 +873,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>unloadRegions</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.398">unloadRegions</a>(boolean&nbsp;unloadFromRack)
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.411">unloadRegions</a>(boolean&nbsp;unloadFromRack)
                        throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/InterruptedException.html?is-external=true" title="class or interface in java.lang">InterruptedException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>,
                               <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a></pre>
@@ -892,7 +892,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <li class="blockList">
 <h4>filterRSGroupServers</h4>
 <pre>@InterfaceAudience.Private
-<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.471">filterRSGroupServers</a>(<a href="../../../../../org/apache/hadoop/hbase/rsgroup/RSGroupInfo.html" title="class in org.a [...]
+<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.484">filterRSGroupServers</a>(<a href="../../../../../org/apache/hadoop/hbase/rsgroup/RSGroupInfo.html" title="class in org.a [...]
                                                                        <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html?is-external=true" title="class or interface in java.util">Collection</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;onlineServers)</pre>
 </li>
 </ul>
@@ -902,7 +902,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>unloadRegions</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.486">unloadRegions</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.499">unloadRegions</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server,
                            <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;regionServers,
                            <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;movedRegions)
                     throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
@@ -918,7 +918,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>submitRegionMovesWhileUnloading</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.509">submitRegionMovesWhileUnloading</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.522">submitRegionMovesWhileUnloading</a>(<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;server,
                                              <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;regionServers,
                                              <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;movedRegions,
                                              <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;regionsToMove)
@@ -935,7 +935,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>waitTaskToFinish</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.532">waitTaskToFinish</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html?is-external=true" title="class or interface in java.util.concurrent">ExecutorService</a>&nbsp;pool,
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.545">waitTaskToFinish</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html?is-external=true" title="class or interface in java.util.concurrent">ExecutorService</a>&nbsp;pool,
                                  <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html?is-external=true" title="class or interface in java.util.concurrent">Future</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&nbsp;task,
                                  <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;operation)
                           throws <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeoutException.html?is-external=true" title="class or interface in java.util.concurrent">TimeoutException</a>,
@@ -955,7 +955,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>waitMoveTasksToFinish</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.556">waitMoveTasksToFinish</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html?is-external=true" title="class or interface in java.util.concurrent">ExecutorService</a>&nbsp;moveRegionsPool,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.569">waitMoveTasksToFinish</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html?is-external=true" title="class or interface in java.util.concurrent">ExecutorService</a>&nbsp;moveRegionsPool,
                                    <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html?is-external=true" title="class or interface in java.util.concurrent">Future</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Boolean.html?is-external=true" title="class or interface in java.lang">Boolean</a>&gt;&g [...]
                                    long&nbsp;timeoutInSeconds)
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
@@ -971,7 +971,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>ignoreRegionMoveFailure</h4>
-<pre>private&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.592">ignoreRegionMoveFailure</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>&nbsp;e)</pre>
+<pre>private&nbsp;boolean&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.605">ignoreRegionMoveFailure</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutionException.html?is-external=true" title="class or interface in java.util.concurrent">ExecutionException</a>&nbsp;e)</pre>
 </li>
 </ul>
 <a name="getTargetServer--">
@@ -980,7 +980,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>getTargetServer</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.608">getTargetServer</a>()
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.621">getTargetServer</a>()
                             throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -994,7 +994,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>readRegionsFromFile</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.636">readRegionsFromFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html [...]
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.649">readRegionsFromFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html [...]
                                       throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="throwsLabel">Throws:</span></dt>
@@ -1008,7 +1008,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>writeFile</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.661">writeFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;filename,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.674">writeFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;filename,
                        <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/client/RegionInfo.html" title="interface in org.apache.hadoop.hbase.client">RegionInfo</a>&gt;&nbsp;movedRegions)
                 throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Write the number of regions moved in the first line followed by regions moved in subsequent
@@ -1025,7 +1025,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>deleteFile</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.675">deleteFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;filename)</pre>
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.688">deleteFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;filename)</pre>
 </li>
 </ul>
 <a name="readServersFromFile-java.lang.String-">
@@ -1034,7 +1034,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>readServersFromFile</h4>
-<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.686">readServersFromFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.h [...]
+<pre>private&nbsp;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&gt;&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.699">readServersFromFile</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.h [...]
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <dl>
 <dt><span class="paramLabel">Parameters:</span></dt>
@@ -1052,7 +1052,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>includeExcludeRegionServers</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.711">includeExcludeRegionServers</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;fileName,
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.724">includeExcludeRegionServers</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;fileName,
                                          <a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;regionServers,
                                          boolean&nbsp;isInclude)
                                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
@@ -1076,7 +1076,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>stripMaster</h4>
-<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.734">stripMaster</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;regionServers)
+<pre>private&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.747">stripMaster</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&gt;&nbsp;regionServers)
                   throws <a href="https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html?is-external=true" title="class or interface in java.io">IOException</a></pre>
 <div class="block">Exclude master from list of RSs to move regions to</div>
 <dl>
@@ -1091,7 +1091,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>stripServer</h4>
-<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.744">stripServer</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hba [...]
+<pre>private&nbsp;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hbase">ServerName</a>&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.757">stripServer</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html?is-external=true" title="class or interface in java.util">List</a>&lt;<a href="../../../../../org/apache/hadoop/hbase/ServerName.html" title="class in org.apache.hadoop.hba [...]
                                <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>&nbsp;hostname,
                                int&nbsp;port)</pre>
 <div class="block">Remove the servername whose hostname and port portion matches from the passed array of servers.
@@ -1108,7 +1108,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>addOptions</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.759">addOptions</a>()</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.772">addOptions</a>()</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/util/AbstractHBaseTool.html#addOptions--">AbstractHBaseTool</a></code></span></div>
 <div class="block">Override this to add command-line options using <a href="../../../../../org/apache/hadoop/hbase/util/AbstractHBaseTool.html#addOptWithArg-java.lang.String-java.lang.String-"><code>AbstractHBaseTool.addOptWithArg(java.lang.String, java.lang.String)</code></a> and similar methods.</div>
 <dl>
@@ -1123,7 +1123,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>processOptions</h4>
-<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.782">processOptions</a>(org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine&nbsp;cmd)</pre>
+<pre>protected&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.795">processOptions</a>(org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine&nbsp;cmd)</pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/util/AbstractHBaseTool.html#processOptions-org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine-">AbstractHBaseTool</a></code></span></div>
 <div class="block">This method is called to process the options after they have been parsed.</div>
 <dl>
@@ -1138,7 +1138,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockList">
 <li class="blockList">
 <h4>doWork</h4>
-<pre>protected&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.807">doWork</a>()
+<pre>protected&nbsp;int&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.820">doWork</a>()
               throws <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Exception.html?is-external=true" title="class or interface in java.lang">Exception</a></pre>
 <div class="block"><span class="descfrmTypeLabel">Description copied from class:&nbsp;<code><a href="../../../../../org/apache/hadoop/hbase/util/AbstractHBaseTool.html#doWork--">AbstractHBaseTool</a></code></span></div>
 <div class="block">The "main function" of the tool</div>
@@ -1156,7 +1156,7 @@ implements <a href="https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.
 <ul class="blockListLast">
 <li class="blockList">
 <h4>main</h4>
-<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.824">main</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]&nbsp;args)</pre>
+<pre>public static&nbsp;void&nbsp;<a href="../../../../../src-html/org/apache/hadoop/hbase/util/RegionMover.html#line.837">main</a>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html?is-external=true" title="class or interface in java.lang">String</a>[]&nbsp;args)</pre>
 </li>
 </ul>
 </li>
diff --git a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
index 3e1b8443c0b..eda67f3cc96 100644
--- a/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
+++ b/devapidocs/org/apache/hadoop/hbase/util/package-tree.html
@@ -536,15 +536,15 @@
 <ul>
 <li type="circle">java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html?is-external=true" title="class or interface in java.lang"><span class="typeNameLink">Enum</span></a>&lt;E&gt; (implements java.lang.<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html?is-external=true" title="class or interface in java.lang">Comparable</a>&lt;T&gt;, java.io.<a href="https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true [...]
 <ul>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PoolMap.PoolType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PoolMap.PoolType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLockWithObjectPool.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLockWithObjectPool.ReferenceType</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PrettyPrinter.Unit.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PrettyPrinter.Unit</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/DNS.ServerType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">DNS.ServerType</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.UnsafeComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.UnsafeComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.PureJavaComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.PureJavaComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/ChecksumType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">ChecksumType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/DNS.ServerType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">DNS.ServerType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Order.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Order</span></a></li>
 <li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/HbckErrorReporter.ERROR_CODE.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">HbckErrorReporter.ERROR_CODE</span></a></li>
-<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.LexicographicalComparerHolder.PureJavaComparer.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">Bytes.LexicographicalComparerHolder.PureJavaComparer</span></a> (implements org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/Bytes.Comparer.html" title="interface in org.apache.hadoop.hbase.util">Bytes.Comparer</a>&lt;T&gt;)</li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/IdReadWriteLockWithObjectPool.ReferenceType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">IdReadWriteLockWithObjectPool.ReferenceType</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PrettyPrinter.Unit.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PrettyPrinter.Unit</span></a></li>
+<li type="circle">org.apache.hadoop.hbase.util.<a href="../../../../../org/apache/hadoop/hbase/util/PoolMap.PoolType.html" title="enum in org.apache.hadoop.hbase.util"><span class="typeNameLink">PoolMap.PoolType</span></a></li>
 </ul>
 </li>
 </ul>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/HBaseServerBase.html b/devapidocs/src-html/org/apache/hadoop/hbase/HBaseServerBase.html
index 13b5ed91126..ae16c800152 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/HBaseServerBase.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/HBaseServerBase.html
@@ -260,386 +260,392 @@
 <span class="sourceLineNo">252</span>      this.rpcServices = createRpcServices();<a name="line.252"></a>
 <span class="sourceLineNo">253</span>      useThisHostnameInstead = getUseThisHostnameInstead(conf);<a name="line.253"></a>
 <span class="sourceLineNo">254</span>      InetSocketAddress addr = rpcServices.getSocketAddress();<a name="line.254"></a>
-<span class="sourceLineNo">255</span>      String hostName = StringUtils.isBlank(useThisHostnameInstead)<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        ? addr.getHostName()<a name="line.256"></a>
-<span class="sourceLineNo">257</span>        : this.useThisHostnameInstead;<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      serverName = ServerName.valueOf(hostName, addr.getPort(), this.startcode);<a name="line.258"></a>
-<span class="sourceLineNo">259</span>      // login the zookeeper client principal (if using security)<a name="line.259"></a>
-<span class="sourceLineNo">260</span>      ZKAuthentication.loginClient(this.conf, HConstants.ZK_CLIENT_KEYTAB_FILE,<a name="line.260"></a>
-<span class="sourceLineNo">261</span>        HConstants.ZK_CLIENT_KERBEROS_PRINCIPAL, hostName);<a name="line.261"></a>
-<span class="sourceLineNo">262</span>      // login the server principal (if using secure Hadoop)<a name="line.262"></a>
-<span class="sourceLineNo">263</span>      login(userProvider, hostName);<a name="line.263"></a>
-<span class="sourceLineNo">264</span>      // init superusers and add the server principal (if using security)<a name="line.264"></a>
-<span class="sourceLineNo">265</span>      // or process owner as default super user.<a name="line.265"></a>
-<span class="sourceLineNo">266</span>      Superusers.initialize(conf);<a name="line.266"></a>
-<span class="sourceLineNo">267</span>      zooKeeper =<a name="line.267"></a>
-<span class="sourceLineNo">268</span>        new ZKWatcher(conf, getProcessName() + ":" + addr.getPort(), this, canCreateBaseZNode());<a name="line.268"></a>
-<span class="sourceLineNo">269</span><a name="line.269"></a>
-<span class="sourceLineNo">270</span>      this.configurationManager = new ConfigurationManager();<a name="line.270"></a>
-<span class="sourceLineNo">271</span>      setupWindows(conf, configurationManager);<a name="line.271"></a>
-<span class="sourceLineNo">272</span><a name="line.272"></a>
-<span class="sourceLineNo">273</span>      initializeFileSystem();<a name="line.273"></a>
-<span class="sourceLineNo">274</span><a name="line.274"></a>
-<span class="sourceLineNo">275</span>      this.choreService = new ChoreService(getName(), true);<a name="line.275"></a>
-<span class="sourceLineNo">276</span>      this.executorService = new ExecutorService(getName());<a name="line.276"></a>
-<span class="sourceLineNo">277</span><a name="line.277"></a>
-<span class="sourceLineNo">278</span>      this.metaRegionLocationCache = new MetaRegionLocationCache(zooKeeper);<a name="line.278"></a>
-<span class="sourceLineNo">279</span><a name="line.279"></a>
-<span class="sourceLineNo">280</span>      if (clusterMode()) {<a name="line.280"></a>
-<span class="sourceLineNo">281</span>        if (<a name="line.281"></a>
-<span class="sourceLineNo">282</span>          conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)<a name="line.282"></a>
-<span class="sourceLineNo">283</span>        ) {<a name="line.283"></a>
-<span class="sourceLineNo">284</span>          csm = new ZkCoordinatedStateManager(this);<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        } else {<a name="line.285"></a>
-<span class="sourceLineNo">286</span>          csm = null;<a name="line.286"></a>
-<span class="sourceLineNo">287</span>        }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>        clusterStatusTracker = new ClusterStatusTracker(zooKeeper, this);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>        clusterStatusTracker.start();<a name="line.289"></a>
-<span class="sourceLineNo">290</span>      } else {<a name="line.290"></a>
-<span class="sourceLineNo">291</span>        csm = null;<a name="line.291"></a>
-<span class="sourceLineNo">292</span>        clusterStatusTracker = null;<a name="line.292"></a>
-<span class="sourceLineNo">293</span>      }<a name="line.293"></a>
-<span class="sourceLineNo">294</span>      putUpWebUI();<a name="line.294"></a>
-<span class="sourceLineNo">295</span>      span.setStatus(StatusCode.OK);<a name="line.295"></a>
-<span class="sourceLineNo">296</span>    } catch (Throwable t) {<a name="line.296"></a>
-<span class="sourceLineNo">297</span>      TraceUtil.setError(span, t);<a name="line.297"></a>
-<span class="sourceLineNo">298</span>      throw t;<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    } finally {<a name="line.299"></a>
-<span class="sourceLineNo">300</span>      span.end();<a name="line.300"></a>
-<span class="sourceLineNo">301</span>    }<a name="line.301"></a>
-<span class="sourceLineNo">302</span>  }<a name="line.302"></a>
-<span class="sourceLineNo">303</span><a name="line.303"></a>
-<span class="sourceLineNo">304</span>  /**<a name="line.304"></a>
-<span class="sourceLineNo">305</span>   * Puts up the webui.<a name="line.305"></a>
-<span class="sourceLineNo">306</span>   */<a name="line.306"></a>
-<span class="sourceLineNo">307</span>  private void putUpWebUI() throws IOException {<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    int port =<a name="line.308"></a>
-<span class="sourceLineNo">309</span>      this.conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT);<a name="line.309"></a>
-<span class="sourceLineNo">310</span>    String addr = this.conf.get("hbase.regionserver.info.bindAddress", "0.0.0.0");<a name="line.310"></a>
-<span class="sourceLineNo">311</span><a name="line.311"></a>
-<span class="sourceLineNo">312</span>    if (this instanceof HMaster) {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>      port = conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT);<a name="line.313"></a>
-<span class="sourceLineNo">314</span>      addr = this.conf.get("hbase.master.info.bindAddress", "0.0.0.0");<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    }<a name="line.315"></a>
-<span class="sourceLineNo">316</span>    // -1 is for disabling info server<a name="line.316"></a>
-<span class="sourceLineNo">317</span>    if (port &lt; 0) {<a name="line.317"></a>
-<span class="sourceLineNo">318</span>      return;<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    }<a name="line.319"></a>
-<span class="sourceLineNo">320</span><a name="line.320"></a>
-<span class="sourceLineNo">321</span>    if (!Addressing.isLocalAddress(InetAddress.getByName(addr))) {<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      String msg = "Failed to start http info server. Address " + addr<a name="line.322"></a>
-<span class="sourceLineNo">323</span>        + " does not belong to this host. Correct configuration parameter: "<a name="line.323"></a>
-<span class="sourceLineNo">324</span>        + "hbase.regionserver.info.bindAddress";<a name="line.324"></a>
-<span class="sourceLineNo">325</span>      LOG.error(msg);<a name="line.325"></a>
-<span class="sourceLineNo">326</span>      throw new IOException(msg);<a name="line.326"></a>
-<span class="sourceLineNo">327</span>    }<a name="line.327"></a>
-<span class="sourceLineNo">328</span>    // check if auto port bind enabled<a name="line.328"></a>
-<span class="sourceLineNo">329</span>    boolean auto = this.conf.getBoolean(HConstants.REGIONSERVER_INFO_PORT_AUTO, false);<a name="line.329"></a>
-<span class="sourceLineNo">330</span>    while (true) {<a name="line.330"></a>
-<span class="sourceLineNo">331</span>      try {<a name="line.331"></a>
-<span class="sourceLineNo">332</span>        this.infoServer = new InfoServer(getProcessName(), addr, port, false, this.conf);<a name="line.332"></a>
-<span class="sourceLineNo">333</span>        infoServer.addPrivilegedServlet("dump", "/dump", getDumpServlet());<a name="line.333"></a>
-<span class="sourceLineNo">334</span>        configureInfoServer(infoServer);<a name="line.334"></a>
-<span class="sourceLineNo">335</span>        this.infoServer.start();<a name="line.335"></a>
-<span class="sourceLineNo">336</span>        break;<a name="line.336"></a>
-<span class="sourceLineNo">337</span>      } catch (BindException e) {<a name="line.337"></a>
-<span class="sourceLineNo">338</span>        if (!auto) {<a name="line.338"></a>
-<span class="sourceLineNo">339</span>          // auto bind disabled throw BindException<a name="line.339"></a>
-<span class="sourceLineNo">340</span>          LOG.error("Failed binding http info server to port: " + port);<a name="line.340"></a>
-<span class="sourceLineNo">341</span>          throw e;<a name="line.341"></a>
-<span class="sourceLineNo">342</span>        }<a name="line.342"></a>
-<span class="sourceLineNo">343</span>        // auto bind enabled, try to use another port<a name="line.343"></a>
-<span class="sourceLineNo">344</span>        LOG.info("Failed binding http info server to port: " + port);<a name="line.344"></a>
-<span class="sourceLineNo">345</span>        port++;<a name="line.345"></a>
-<span class="sourceLineNo">346</span>        LOG.info("Retry starting http info server with port: " + port);<a name="line.346"></a>
-<span class="sourceLineNo">347</span>      }<a name="line.347"></a>
-<span class="sourceLineNo">348</span>    }<a name="line.348"></a>
-<span class="sourceLineNo">349</span>    port = this.infoServer.getPort();<a name="line.349"></a>
-<span class="sourceLineNo">350</span>    conf.setInt(HConstants.REGIONSERVER_INFO_PORT, port);<a name="line.350"></a>
-<span class="sourceLineNo">351</span>    int masterInfoPort =<a name="line.351"></a>
-<span class="sourceLineNo">352</span>      conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT);<a name="line.352"></a>
-<span class="sourceLineNo">353</span>    conf.setInt("hbase.master.info.port.orig", masterInfoPort);<a name="line.353"></a>
-<span class="sourceLineNo">354</span>    conf.setInt(HConstants.MASTER_INFO_PORT, port);<a name="line.354"></a>
-<span class="sourceLineNo">355</span>  }<a name="line.355"></a>
-<span class="sourceLineNo">356</span><a name="line.356"></a>
-<span class="sourceLineNo">357</span>  /**<a name="line.357"></a>
-<span class="sourceLineNo">358</span>   * Sets the abort state if not already set.<a name="line.358"></a>
-<span class="sourceLineNo">359</span>   * @return True if abortRequested set to True successfully, false if an abort is already in<a name="line.359"></a>
-<span class="sourceLineNo">360</span>   *         progress.<a name="line.360"></a>
-<span class="sourceLineNo">361</span>   */<a name="line.361"></a>
-<span class="sourceLineNo">362</span>  protected final boolean setAbortRequested() {<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    return abortRequested.compareAndSet(false, true);<a name="line.363"></a>
-<span class="sourceLineNo">364</span>  }<a name="line.364"></a>
-<span class="sourceLineNo">365</span><a name="line.365"></a>
-<span class="sourceLineNo">366</span>  @Override<a name="line.366"></a>
-<span class="sourceLineNo">367</span>  public boolean isStopped() {<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    return stopped;<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  }<a name="line.369"></a>
-<span class="sourceLineNo">370</span><a name="line.370"></a>
-<span class="sourceLineNo">371</span>  @Override<a name="line.371"></a>
-<span class="sourceLineNo">372</span>  public boolean isAborted() {<a name="line.372"></a>
-<span class="sourceLineNo">373</span>    return abortRequested.get();<a name="line.373"></a>
-<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
-<span class="sourceLineNo">375</span><a name="line.375"></a>
-<span class="sourceLineNo">376</span>  @Override<a name="line.376"></a>
-<span class="sourceLineNo">377</span>  public Configuration getConfiguration() {<a name="line.377"></a>
-<span class="sourceLineNo">378</span>    return conf;<a name="line.378"></a>
-<span class="sourceLineNo">379</span>  }<a name="line.379"></a>
-<span class="sourceLineNo">380</span><a name="line.380"></a>
-<span class="sourceLineNo">381</span>  @Override<a name="line.381"></a>
-<span class="sourceLineNo">382</span>  public AsyncClusterConnection getAsyncClusterConnection() {<a name="line.382"></a>
-<span class="sourceLineNo">383</span>    return asyncClusterConnection;<a name="line.383"></a>
-<span class="sourceLineNo">384</span>  }<a name="line.384"></a>
-<span class="sourceLineNo">385</span><a name="line.385"></a>
-<span class="sourceLineNo">386</span>  @Override<a name="line.386"></a>
-<span class="sourceLineNo">387</span>  public ZKWatcher getZooKeeper() {<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    return zooKeeper;<a name="line.388"></a>
-<span class="sourceLineNo">389</span>  }<a name="line.389"></a>
-<span class="sourceLineNo">390</span><a name="line.390"></a>
-<span class="sourceLineNo">391</span>  protected final void shutdownChore(ScheduledChore chore) {<a name="line.391"></a>
-<span class="sourceLineNo">392</span>    if (chore != null) {<a name="line.392"></a>
-<span class="sourceLineNo">393</span>      chore.shutdown();<a name="line.393"></a>
-<span class="sourceLineNo">394</span>    }<a name="line.394"></a>
+<span class="sourceLineNo">255</span><a name="line.255"></a>
+<span class="sourceLineNo">256</span>      // if use-ip is enabled, we will use ip to expose Master/RS service for client,<a name="line.256"></a>
+<span class="sourceLineNo">257</span>      // see HBASE-27304 for details.<a name="line.257"></a>
+<span class="sourceLineNo">258</span>      boolean useIp = conf.getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY,<a name="line.258"></a>
+<span class="sourceLineNo">259</span>        HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT);<a name="line.259"></a>
+<span class="sourceLineNo">260</span>      String isaHostName =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>        useIp ? addr.getAddress().getHostAddress() : addr.getAddress().getHostName();<a name="line.261"></a>
+<span class="sourceLineNo">262</span>      String hostName =<a name="line.262"></a>
+<span class="sourceLineNo">263</span>        StringUtils.isBlank(useThisHostnameInstead) ? isaHostName : useThisHostnameInstead;<a name="line.263"></a>
+<span class="sourceLineNo">264</span>      serverName = ServerName.valueOf(hostName, addr.getPort(), this.startcode);<a name="line.264"></a>
+<span class="sourceLineNo">265</span>      // login the zookeeper client principal (if using security)<a name="line.265"></a>
+<span class="sourceLineNo">266</span>      ZKAuthentication.loginClient(this.conf, HConstants.ZK_CLIENT_KEYTAB_FILE,<a name="line.266"></a>
+<span class="sourceLineNo">267</span>        HConstants.ZK_CLIENT_KERBEROS_PRINCIPAL, hostName);<a name="line.267"></a>
+<span class="sourceLineNo">268</span>      // login the server principal (if using secure Hadoop)<a name="line.268"></a>
+<span class="sourceLineNo">269</span>      login(userProvider, hostName);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>      // init superusers and add the server principal (if using security)<a name="line.270"></a>
+<span class="sourceLineNo">271</span>      // or process owner as default super user.<a name="line.271"></a>
+<span class="sourceLineNo">272</span>      Superusers.initialize(conf);<a name="line.272"></a>
+<span class="sourceLineNo">273</span>      zooKeeper =<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        new ZKWatcher(conf, getProcessName() + ":" + addr.getPort(), this, canCreateBaseZNode());<a name="line.274"></a>
+<span class="sourceLineNo">275</span><a name="line.275"></a>
+<span class="sourceLineNo">276</span>      this.configurationManager = new ConfigurationManager();<a name="line.276"></a>
+<span class="sourceLineNo">277</span>      setupWindows(conf, configurationManager);<a name="line.277"></a>
+<span class="sourceLineNo">278</span><a name="line.278"></a>
+<span class="sourceLineNo">279</span>      initializeFileSystem();<a name="line.279"></a>
+<span class="sourceLineNo">280</span><a name="line.280"></a>
+<span class="sourceLineNo">281</span>      this.choreService = new ChoreService(getName(), true);<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      this.executorService = new ExecutorService(getName());<a name="line.282"></a>
+<span class="sourceLineNo">283</span><a name="line.283"></a>
+<span class="sourceLineNo">284</span>      this.metaRegionLocationCache = new MetaRegionLocationCache(zooKeeper);<a name="line.284"></a>
+<span class="sourceLineNo">285</span><a name="line.285"></a>
+<span class="sourceLineNo">286</span>      if (clusterMode()) {<a name="line.286"></a>
+<span class="sourceLineNo">287</span>        if (<a name="line.287"></a>
+<span class="sourceLineNo">288</span>          conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)<a name="line.288"></a>
+<span class="sourceLineNo">289</span>        ) {<a name="line.289"></a>
+<span class="sourceLineNo">290</span>          csm = new ZkCoordinatedStateManager(this);<a name="line.290"></a>
+<span class="sourceLineNo">291</span>        } else {<a name="line.291"></a>
+<span class="sourceLineNo">292</span>          csm = null;<a name="line.292"></a>
+<span class="sourceLineNo">293</span>        }<a name="line.293"></a>
+<span class="sourceLineNo">294</span>        clusterStatusTracker = new ClusterStatusTracker(zooKeeper, this);<a name="line.294"></a>
+<span class="sourceLineNo">295</span>        clusterStatusTracker.start();<a name="line.295"></a>
+<span class="sourceLineNo">296</span>      } else {<a name="line.296"></a>
+<span class="sourceLineNo">297</span>        csm = null;<a name="line.297"></a>
+<span class="sourceLineNo">298</span>        clusterStatusTracker = null;<a name="line.298"></a>
+<span class="sourceLineNo">299</span>      }<a name="line.299"></a>
+<span class="sourceLineNo">300</span>      putUpWebUI();<a name="line.300"></a>
+<span class="sourceLineNo">301</span>      span.setStatus(StatusCode.OK);<a name="line.301"></a>
+<span class="sourceLineNo">302</span>    } catch (Throwable t) {<a name="line.302"></a>
+<span class="sourceLineNo">303</span>      TraceUtil.setError(span, t);<a name="line.303"></a>
+<span class="sourceLineNo">304</span>      throw t;<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    } finally {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      span.end();<a name="line.306"></a>
+<span class="sourceLineNo">307</span>    }<a name="line.307"></a>
+<span class="sourceLineNo">308</span>  }<a name="line.308"></a>
+<span class="sourceLineNo">309</span><a name="line.309"></a>
+<span class="sourceLineNo">310</span>  /**<a name="line.310"></a>
+<span class="sourceLineNo">311</span>   * Puts up the webui.<a name="line.311"></a>
+<span class="sourceLineNo">312</span>   */<a name="line.312"></a>
+<span class="sourceLineNo">313</span>  private void putUpWebUI() throws IOException {<a name="line.313"></a>
+<span class="sourceLineNo">314</span>    int port =<a name="line.314"></a>
+<span class="sourceLineNo">315</span>      this.conf.getInt(HConstants.REGIONSERVER_INFO_PORT, HConstants.DEFAULT_REGIONSERVER_INFOPORT);<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    String addr = this.conf.get("hbase.regionserver.info.bindAddress", "0.0.0.0");<a name="line.316"></a>
+<span class="sourceLineNo">317</span><a name="line.317"></a>
+<span class="sourceLineNo">318</span>    if (this instanceof HMaster) {<a name="line.318"></a>
+<span class="sourceLineNo">319</span>      port = conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT);<a name="line.319"></a>
+<span class="sourceLineNo">320</span>      addr = this.conf.get("hbase.master.info.bindAddress", "0.0.0.0");<a name="line.320"></a>
+<span class="sourceLineNo">321</span>    }<a name="line.321"></a>
+<span class="sourceLineNo">322</span>    // -1 is for disabling info server<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    if (port &lt; 0) {<a name="line.323"></a>
+<span class="sourceLineNo">324</span>      return;<a name="line.324"></a>
+<span class="sourceLineNo">325</span>    }<a name="line.325"></a>
+<span class="sourceLineNo">326</span><a name="line.326"></a>
+<span class="sourceLineNo">327</span>    if (!Addressing.isLocalAddress(InetAddress.getByName(addr))) {<a name="line.327"></a>
+<span class="sourceLineNo">328</span>      String msg = "Failed to start http info server. Address " + addr<a name="line.328"></a>
+<span class="sourceLineNo">329</span>        + " does not belong to this host. Correct configuration parameter: "<a name="line.329"></a>
+<span class="sourceLineNo">330</span>        + "hbase.regionserver.info.bindAddress";<a name="line.330"></a>
+<span class="sourceLineNo">331</span>      LOG.error(msg);<a name="line.331"></a>
+<span class="sourceLineNo">332</span>      throw new IOException(msg);<a name="line.332"></a>
+<span class="sourceLineNo">333</span>    }<a name="line.333"></a>
+<span class="sourceLineNo">334</span>    // check if auto port bind enabled<a name="line.334"></a>
+<span class="sourceLineNo">335</span>    boolean auto = this.conf.getBoolean(HConstants.REGIONSERVER_INFO_PORT_AUTO, false);<a name="line.335"></a>
+<span class="sourceLineNo">336</span>    while (true) {<a name="line.336"></a>
+<span class="sourceLineNo">337</span>      try {<a name="line.337"></a>
+<span class="sourceLineNo">338</span>        this.infoServer = new InfoServer(getProcessName(), addr, port, false, this.conf);<a name="line.338"></a>
+<span class="sourceLineNo">339</span>        infoServer.addPrivilegedServlet("dump", "/dump", getDumpServlet());<a name="line.339"></a>
+<span class="sourceLineNo">340</span>        configureInfoServer(infoServer);<a name="line.340"></a>
+<span class="sourceLineNo">341</span>        this.infoServer.start();<a name="line.341"></a>
+<span class="sourceLineNo">342</span>        break;<a name="line.342"></a>
+<span class="sourceLineNo">343</span>      } catch (BindException e) {<a name="line.343"></a>
+<span class="sourceLineNo">344</span>        if (!auto) {<a name="line.344"></a>
+<span class="sourceLineNo">345</span>          // auto bind disabled throw BindException<a name="line.345"></a>
+<span class="sourceLineNo">346</span>          LOG.error("Failed binding http info server to port: " + port);<a name="line.346"></a>
+<span class="sourceLineNo">347</span>          throw e;<a name="line.347"></a>
+<span class="sourceLineNo">348</span>        }<a name="line.348"></a>
+<span class="sourceLineNo">349</span>        // auto bind enabled, try to use another port<a name="line.349"></a>
+<span class="sourceLineNo">350</span>        LOG.info("Failed binding http info server to port: " + port);<a name="line.350"></a>
+<span class="sourceLineNo">351</span>        port++;<a name="line.351"></a>
+<span class="sourceLineNo">352</span>        LOG.info("Retry starting http info server with port: " + port);<a name="line.352"></a>
+<span class="sourceLineNo">353</span>      }<a name="line.353"></a>
+<span class="sourceLineNo">354</span>    }<a name="line.354"></a>
+<span class="sourceLineNo">355</span>    port = this.infoServer.getPort();<a name="line.355"></a>
+<span class="sourceLineNo">356</span>    conf.setInt(HConstants.REGIONSERVER_INFO_PORT, port);<a name="line.356"></a>
+<span class="sourceLineNo">357</span>    int masterInfoPort =<a name="line.357"></a>
+<span class="sourceLineNo">358</span>      conf.getInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT);<a name="line.358"></a>
+<span class="sourceLineNo">359</span>    conf.setInt("hbase.master.info.port.orig", masterInfoPort);<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    conf.setInt(HConstants.MASTER_INFO_PORT, port);<a name="line.360"></a>
+<span class="sourceLineNo">361</span>  }<a name="line.361"></a>
+<span class="sourceLineNo">362</span><a name="line.362"></a>
+<span class="sourceLineNo">363</span>  /**<a name="line.363"></a>
+<span class="sourceLineNo">364</span>   * Sets the abort state if not already set.<a name="line.364"></a>
+<span class="sourceLineNo">365</span>   * @return True if abortRequested set to True successfully, false if an abort is already in<a name="line.365"></a>
+<span class="sourceLineNo">366</span>   *         progress.<a name="line.366"></a>
+<span class="sourceLineNo">367</span>   */<a name="line.367"></a>
+<span class="sourceLineNo">368</span>  protected final boolean setAbortRequested() {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>    return abortRequested.compareAndSet(false, true);<a name="line.369"></a>
+<span class="sourceLineNo">370</span>  }<a name="line.370"></a>
+<span class="sourceLineNo">371</span><a name="line.371"></a>
+<span class="sourceLineNo">372</span>  @Override<a name="line.372"></a>
+<span class="sourceLineNo">373</span>  public boolean isStopped() {<a name="line.373"></a>
+<span class="sourceLineNo">374</span>    return stopped;<a name="line.374"></a>
+<span class="sourceLineNo">375</span>  }<a name="line.375"></a>
+<span class="sourceLineNo">376</span><a name="line.376"></a>
+<span class="sourceLineNo">377</span>  @Override<a name="line.377"></a>
+<span class="sourceLineNo">378</span>  public boolean isAborted() {<a name="line.378"></a>
+<span class="sourceLineNo">379</span>    return abortRequested.get();<a name="line.379"></a>
+<span class="sourceLineNo">380</span>  }<a name="line.380"></a>
+<span class="sourceLineNo">381</span><a name="line.381"></a>
+<span class="sourceLineNo">382</span>  @Override<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  public Configuration getConfiguration() {<a name="line.383"></a>
+<span class="sourceLineNo">384</span>    return conf;<a name="line.384"></a>
+<span class="sourceLineNo">385</span>  }<a name="line.385"></a>
+<span class="sourceLineNo">386</span><a name="line.386"></a>
+<span class="sourceLineNo">387</span>  @Override<a name="line.387"></a>
+<span class="sourceLineNo">388</span>  public AsyncClusterConnection getAsyncClusterConnection() {<a name="line.388"></a>
+<span class="sourceLineNo">389</span>    return asyncClusterConnection;<a name="line.389"></a>
+<span class="sourceLineNo">390</span>  }<a name="line.390"></a>
+<span class="sourceLineNo">391</span><a name="line.391"></a>
+<span class="sourceLineNo">392</span>  @Override<a name="line.392"></a>
+<span class="sourceLineNo">393</span>  public ZKWatcher getZooKeeper() {<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    return zooKeeper;<a name="line.394"></a>
 <span class="sourceLineNo">395</span>  }<a name="line.395"></a>
 <span class="sourceLineNo">396</span><a name="line.396"></a>
-<span class="sourceLineNo">397</span>  protected final void initializeMemStoreChunkCreator(HeapMemoryManager hMemManager) {<a name="line.397"></a>
-<span class="sourceLineNo">398</span>    if (MemStoreLAB.isEnabled(conf)) {<a name="line.398"></a>
-<span class="sourceLineNo">399</span>      // MSLAB is enabled. So initialize MemStoreChunkPool<a name="line.399"></a>
-<span class="sourceLineNo">400</span>      // By this time, the MemstoreFlusher is already initialized. We can get the global limits from<a name="line.400"></a>
-<span class="sourceLineNo">401</span>      // it.<a name="line.401"></a>
-<span class="sourceLineNo">402</span>      Pair&lt;Long, MemoryType&gt; pair = MemorySizeUtil.getGlobalMemStoreSize(conf);<a name="line.402"></a>
-<span class="sourceLineNo">403</span>      long globalMemStoreSize = pair.getFirst();<a name="line.403"></a>
-<span class="sourceLineNo">404</span>      boolean offheap = pair.getSecond() == MemoryType.NON_HEAP;<a name="line.404"></a>
-<span class="sourceLineNo">405</span>      // When off heap memstore in use, take full area for chunk pool.<a name="line.405"></a>
-<span class="sourceLineNo">406</span>      float poolSizePercentage = offheap<a name="line.406"></a>
-<span class="sourceLineNo">407</span>        ? 1.0F<a name="line.407"></a>
-<span class="sourceLineNo">408</span>        : conf.getFloat(MemStoreLAB.CHUNK_POOL_MAXSIZE_KEY, MemStoreLAB.POOL_MAX_SIZE_DEFAULT);<a name="line.408"></a>
-<span class="sourceLineNo">409</span>      float initialCountPercentage = conf.getFloat(MemStoreLAB.CHUNK_POOL_INITIALSIZE_KEY,<a name="line.409"></a>
-<span class="sourceLineNo">410</span>        MemStoreLAB.POOL_INITIAL_SIZE_DEFAULT);<a name="line.410"></a>
-<span class="sourceLineNo">411</span>      int chunkSize = conf.getInt(MemStoreLAB.CHUNK_SIZE_KEY, MemStoreLAB.CHUNK_SIZE_DEFAULT);<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      float indexChunkSizePercent = conf.getFloat(MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_KEY,<a name="line.412"></a>
-<span class="sourceLineNo">413</span>        MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);<a name="line.413"></a>
-<span class="sourceLineNo">414</span>      // init the chunkCreator<a name="line.414"></a>
-<span class="sourceLineNo">415</span>      ChunkCreator.initialize(chunkSize, offheap, globalMemStoreSize, poolSizePercentage,<a name="line.415"></a>
-<span class="sourceLineNo">416</span>        initialCountPercentage, hMemManager, indexChunkSizePercent);<a name="line.416"></a>
-<span class="sourceLineNo">417</span>    }<a name="line.417"></a>
-<span class="sourceLineNo">418</span>  }<a name="line.418"></a>
-<span class="sourceLineNo">419</span><a name="line.419"></a>
-<span class="sourceLineNo">420</span>  protected abstract void stopChores();<a name="line.420"></a>
-<span class="sourceLineNo">421</span><a name="line.421"></a>
-<span class="sourceLineNo">422</span>  protected final void stopChoreService() {<a name="line.422"></a>
-<span class="sourceLineNo">423</span>    // clean up the scheduled chores<a name="line.423"></a>
-<span class="sourceLineNo">424</span>    if (choreService != null) {<a name="line.424"></a>
-<span class="sourceLineNo">425</span>      LOG.info("Shutdown chores and chore service");<a name="line.425"></a>
-<span class="sourceLineNo">426</span>      stopChores();<a name="line.426"></a>
-<span class="sourceLineNo">427</span>      // cancel the remaining scheduled chores (in case we missed out any)<a name="line.427"></a>
-<span class="sourceLineNo">428</span>      // TODO: cancel will not cleanup the chores, so we need make sure we do not miss any<a name="line.428"></a>
-<span class="sourceLineNo">429</span>      choreService.shutdown();<a name="line.429"></a>
-<span class="sourceLineNo">430</span>    }<a name="line.430"></a>
-<span class="sourceLineNo">431</span>  }<a name="line.431"></a>
-<span class="sourceLineNo">432</span><a name="line.432"></a>
-<span class="sourceLineNo">433</span>  protected final void stopExecutorService() {<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    if (executorService != null) {<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      LOG.info("Shutdown executor service");<a name="line.435"></a>
-<span class="sourceLineNo">436</span>      executorService.shutdown();<a name="line.436"></a>
-<span class="sourceLineNo">437</span>    }<a name="line.437"></a>
-<span class="sourceLineNo">438</span>  }<a name="line.438"></a>
-<span class="sourceLineNo">439</span><a name="line.439"></a>
-<span class="sourceLineNo">440</span>  protected final void closeClusterConnection() {<a name="line.440"></a>
-<span class="sourceLineNo">441</span>    if (asyncClusterConnection != null) {<a name="line.441"></a>
-<span class="sourceLineNo">442</span>      LOG.info("Close async cluster connection");<a name="line.442"></a>
-<span class="sourceLineNo">443</span>      try {<a name="line.443"></a>
-<span class="sourceLineNo">444</span>        this.asyncClusterConnection.close();<a name="line.444"></a>
-<span class="sourceLineNo">445</span>      } catch (IOException e) {<a name="line.445"></a>
-<span class="sourceLineNo">446</span>        // Although the {@link Closeable} interface throws an {@link<a name="line.446"></a>
-<span class="sourceLineNo">447</span>        // IOException}, in reality, the implementation would never do that.<a name="line.447"></a>
-<span class="sourceLineNo">448</span>        LOG.warn("Attempt to close server's AsyncClusterConnection failed.", e);<a name="line.448"></a>
-<span class="sourceLineNo">449</span>      }<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    }<a name="line.450"></a>
-<span class="sourceLineNo">451</span>  }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>  protected final void stopInfoServer() {<a name="line.453"></a>
-<span class="sourceLineNo">454</span>    if (this.infoServer != null) {<a name="line.454"></a>
-<span class="sourceLineNo">455</span>      LOG.info("Stop info server");<a name="line.455"></a>
-<span class="sourceLineNo">456</span>      try {<a name="line.456"></a>
-<span class="sourceLineNo">457</span>        this.infoServer.stop();<a name="line.457"></a>
-<span class="sourceLineNo">458</span>      } catch (Exception e) {<a name="line.458"></a>
-<span class="sourceLineNo">459</span>        LOG.error("Failed to stop infoServer", e);<a name="line.459"></a>
-<span class="sourceLineNo">460</span>      }<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    }<a name="line.461"></a>
-<span class="sourceLineNo">462</span>  }<a name="line.462"></a>
-<span class="sourceLineNo">463</span><a name="line.463"></a>
-<span class="sourceLineNo">464</span>  protected final void closeZooKeeper() {<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    if (this.zooKeeper != null) {<a name="line.465"></a>
-<span class="sourceLineNo">466</span>      LOG.info("Close zookeeper");<a name="line.466"></a>
-<span class="sourceLineNo">467</span>      this.zooKeeper.close();<a name="line.467"></a>
-<span class="sourceLineNo">468</span>    }<a name="line.468"></a>
-<span class="sourceLineNo">469</span>  }<a name="line.469"></a>
-<span class="sourceLineNo">470</span><a name="line.470"></a>
-<span class="sourceLineNo">471</span>  protected final void closeTableDescriptors() {<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    if (this.tableDescriptors != null) {<a name="line.472"></a>
-<span class="sourceLineNo">473</span>      LOG.info("Close table descriptors");<a name="line.473"></a>
-<span class="sourceLineNo">474</span>      try {<a name="line.474"></a>
-<span class="sourceLineNo">475</span>        this.tableDescriptors.close();<a name="line.475"></a>
-<span class="sourceLineNo">476</span>      } catch (IOException e) {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>        LOG.debug("Failed to close table descriptors gracefully", e);<a name="line.477"></a>
-<span class="sourceLineNo">478</span>      }<a name="line.478"></a>
-<span class="sourceLineNo">479</span>    }<a name="line.479"></a>
-<span class="sourceLineNo">480</span>  }<a name="line.480"></a>
-<span class="sourceLineNo">481</span><a name="line.481"></a>
-<span class="sourceLineNo">482</span>  /**<a name="line.482"></a>
-<span class="sourceLineNo">483</span>   * In order to register ShutdownHook, this method is called when HMaster and HRegionServer are<a name="line.483"></a>
-<span class="sourceLineNo">484</span>   * started. For details, please refer to HBASE-26951<a name="line.484"></a>
-<span class="sourceLineNo">485</span>   */<a name="line.485"></a>
-<span class="sourceLineNo">486</span>  protected final void installShutdownHook() {<a name="line.486"></a>
-<span class="sourceLineNo">487</span>    ShutdownHook.install(conf, dataFs, this, Thread.currentThread());<a name="line.487"></a>
-<span class="sourceLineNo">488</span>    isShutdownHookInstalled = true;<a name="line.488"></a>
-<span class="sourceLineNo">489</span>  }<a name="line.489"></a>
-<span class="sourceLineNo">490</span><a name="line.490"></a>
-<span class="sourceLineNo">491</span>  @RestrictedApi(explanation = "Should only be called in tests", link = "",<a name="line.491"></a>
-<span class="sourceLineNo">492</span>      allowedOnPath = ".*/src/test/.*")<a name="line.492"></a>
-<span class="sourceLineNo">493</span>  public boolean isShutdownHookInstalled() {<a name="line.493"></a>
-<span class="sourceLineNo">494</span>    return isShutdownHookInstalled;<a name="line.494"></a>
+<span class="sourceLineNo">397</span>  protected final void shutdownChore(ScheduledChore chore) {<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    if (chore != null) {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>      chore.shutdown();<a name="line.399"></a>
+<span class="sourceLineNo">400</span>    }<a name="line.400"></a>
+<span class="sourceLineNo">401</span>  }<a name="line.401"></a>
+<span class="sourceLineNo">402</span><a name="line.402"></a>
+<span class="sourceLineNo">403</span>  protected final void initializeMemStoreChunkCreator(HeapMemoryManager hMemManager) {<a name="line.403"></a>
+<span class="sourceLineNo">404</span>    if (MemStoreLAB.isEnabled(conf)) {<a name="line.404"></a>
+<span class="sourceLineNo">405</span>      // MSLAB is enabled. So initialize MemStoreChunkPool<a name="line.405"></a>
+<span class="sourceLineNo">406</span>      // By this time, the MemstoreFlusher is already initialized. We can get the global limits from<a name="line.406"></a>
+<span class="sourceLineNo">407</span>      // it.<a name="line.407"></a>
+<span class="sourceLineNo">408</span>      Pair&lt;Long, MemoryType&gt; pair = MemorySizeUtil.getGlobalMemStoreSize(conf);<a name="line.408"></a>
+<span class="sourceLineNo">409</span>      long globalMemStoreSize = pair.getFirst();<a name="line.409"></a>
+<span class="sourceLineNo">410</span>      boolean offheap = pair.getSecond() == MemoryType.NON_HEAP;<a name="line.410"></a>
+<span class="sourceLineNo">411</span>      // When off heap memstore in use, take full area for chunk pool.<a name="line.411"></a>
+<span class="sourceLineNo">412</span>      float poolSizePercentage = offheap<a name="line.412"></a>
+<span class="sourceLineNo">413</span>        ? 1.0F<a name="line.413"></a>
+<span class="sourceLineNo">414</span>        : conf.getFloat(MemStoreLAB.CHUNK_POOL_MAXSIZE_KEY, MemStoreLAB.POOL_MAX_SIZE_DEFAULT);<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      float initialCountPercentage = conf.getFloat(MemStoreLAB.CHUNK_POOL_INITIALSIZE_KEY,<a name="line.415"></a>
+<span class="sourceLineNo">416</span>        MemStoreLAB.POOL_INITIAL_SIZE_DEFAULT);<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      int chunkSize = conf.getInt(MemStoreLAB.CHUNK_SIZE_KEY, MemStoreLAB.CHUNK_SIZE_DEFAULT);<a name="line.417"></a>
+<span class="sourceLineNo">418</span>      float indexChunkSizePercent = conf.getFloat(MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_KEY,<a name="line.418"></a>
+<span class="sourceLineNo">419</span>        MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);<a name="line.419"></a>
+<span class="sourceLineNo">420</span>      // init the chunkCreator<a name="line.420"></a>
+<span class="sourceLineNo">421</span>      ChunkCreator.initialize(chunkSize, offheap, globalMemStoreSize, poolSizePercentage,<a name="line.421"></a>
+<span class="sourceLineNo">422</span>        initialCountPercentage, hMemManager, indexChunkSizePercent);<a name="line.422"></a>
+<span class="sourceLineNo">423</span>    }<a name="line.423"></a>
+<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
+<span class="sourceLineNo">425</span><a name="line.425"></a>
+<span class="sourceLineNo">426</span>  protected abstract void stopChores();<a name="line.426"></a>
+<span class="sourceLineNo">427</span><a name="line.427"></a>
+<span class="sourceLineNo">428</span>  protected final void stopChoreService() {<a name="line.428"></a>
+<span class="sourceLineNo">429</span>    // clean up the scheduled chores<a name="line.429"></a>
+<span class="sourceLineNo">430</span>    if (choreService != null) {<a name="line.430"></a>
+<span class="sourceLineNo">431</span>      LOG.info("Shutdown chores and chore service");<a name="line.431"></a>
+<span class="sourceLineNo">432</span>      stopChores();<a name="line.432"></a>
+<span class="sourceLineNo">433</span>      // cancel the remaining scheduled chores (in case we missed out any)<a name="line.433"></a>
+<span class="sourceLineNo">434</span>      // TODO: cancel will not cleanup the chores, so we need make sure we do not miss any<a name="line.434"></a>
+<span class="sourceLineNo">435</span>      choreService.shutdown();<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    }<a name="line.436"></a>
+<span class="sourceLineNo">437</span>  }<a name="line.437"></a>
+<span class="sourceLineNo">438</span><a name="line.438"></a>
+<span class="sourceLineNo">439</span>  protected final void stopExecutorService() {<a name="line.439"></a>
+<span class="sourceLineNo">440</span>    if (executorService != null) {<a name="line.440"></a>
+<span class="sourceLineNo">441</span>      LOG.info("Shutdown executor service");<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      executorService.shutdown();<a name="line.442"></a>
+<span class="sourceLineNo">443</span>    }<a name="line.443"></a>
+<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
+<span class="sourceLineNo">445</span><a name="line.445"></a>
+<span class="sourceLineNo">446</span>  protected final void closeClusterConnection() {<a name="line.446"></a>
+<span class="sourceLineNo">447</span>    if (asyncClusterConnection != null) {<a name="line.447"></a>
+<span class="sourceLineNo">448</span>      LOG.info("Close async cluster connection");<a name="line.448"></a>
+<span class="sourceLineNo">449</span>      try {<a name="line.449"></a>
+<span class="sourceLineNo">450</span>        this.asyncClusterConnection.close();<a name="line.450"></a>
+<span class="sourceLineNo">451</span>      } catch (IOException e) {<a name="line.451"></a>
+<span class="sourceLineNo">452</span>        // Although the {@link Closeable} interface throws an {@link<a name="line.452"></a>
+<span class="sourceLineNo">453</span>        // IOException}, in reality, the implementation would never do that.<a name="line.453"></a>
+<span class="sourceLineNo">454</span>        LOG.warn("Attempt to close server's AsyncClusterConnection failed.", e);<a name="line.454"></a>
+<span class="sourceLineNo">455</span>      }<a name="line.455"></a>
+<span class="sourceLineNo">456</span>    }<a name="line.456"></a>
+<span class="sourceLineNo">457</span>  }<a name="line.457"></a>
+<span class="sourceLineNo">458</span><a name="line.458"></a>
+<span class="sourceLineNo">459</span>  protected final void stopInfoServer() {<a name="line.459"></a>
+<span class="sourceLineNo">460</span>    if (this.infoServer != null) {<a name="line.460"></a>
+<span class="sourceLineNo">461</span>      LOG.info("Stop info server");<a name="line.461"></a>
+<span class="sourceLineNo">462</span>      try {<a name="line.462"></a>
+<span class="sourceLineNo">463</span>        this.infoServer.stop();<a name="line.463"></a>
+<span class="sourceLineNo">464</span>      } catch (Exception e) {<a name="line.464"></a>
+<span class="sourceLineNo">465</span>        LOG.error("Failed to stop infoServer", e);<a name="line.465"></a>
+<span class="sourceLineNo">466</span>      }<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    }<a name="line.467"></a>
+<span class="sourceLineNo">468</span>  }<a name="line.468"></a>
+<span class="sourceLineNo">469</span><a name="line.469"></a>
+<span class="sourceLineNo">470</span>  protected final void closeZooKeeper() {<a name="line.470"></a>
+<span class="sourceLineNo">471</span>    if (this.zooKeeper != null) {<a name="line.471"></a>
+<span class="sourceLineNo">472</span>      LOG.info("Close zookeeper");<a name="line.472"></a>
+<span class="sourceLineNo">473</span>      this.zooKeeper.close();<a name="line.473"></a>
+<span class="sourceLineNo">474</span>    }<a name="line.474"></a>
+<span class="sourceLineNo">475</span>  }<a name="line.475"></a>
+<span class="sourceLineNo">476</span><a name="line.476"></a>
+<span class="sourceLineNo">477</span>  protected final void closeTableDescriptors() {<a name="line.477"></a>
+<span class="sourceLineNo">478</span>    if (this.tableDescriptors != null) {<a name="line.478"></a>
+<span class="sourceLineNo">479</span>      LOG.info("Close table descriptors");<a name="line.479"></a>
+<span class="sourceLineNo">480</span>      try {<a name="line.480"></a>
+<span class="sourceLineNo">481</span>        this.tableDescriptors.close();<a name="line.481"></a>
+<span class="sourceLineNo">482</span>      } catch (IOException e) {<a name="line.482"></a>
+<span class="sourceLineNo">483</span>        LOG.debug("Failed to close table descriptors gracefully", e);<a name="line.483"></a>
+<span class="sourceLineNo">484</span>      }<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    }<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  /**<a name="line.488"></a>
+<span class="sourceLineNo">489</span>   * In order to register ShutdownHook, this method is called when HMaster and HRegionServer are<a name="line.489"></a>
+<span class="sourceLineNo">490</span>   * started. For details, please refer to HBASE-26951<a name="line.490"></a>
+<span class="sourceLineNo">491</span>   */<a name="line.491"></a>
+<span class="sourceLineNo">492</span>  protected final void installShutdownHook() {<a name="line.492"></a>
+<span class="sourceLineNo">493</span>    ShutdownHook.install(conf, dataFs, this, Thread.currentThread());<a name="line.493"></a>
+<span class="sourceLineNo">494</span>    isShutdownHookInstalled = true;<a name="line.494"></a>
 <span class="sourceLineNo">495</span>  }<a name="line.495"></a>
 <span class="sourceLineNo">496</span><a name="line.496"></a>
-<span class="sourceLineNo">497</span>  @Override<a name="line.497"></a>
-<span class="sourceLineNo">498</span>  public ServerName getServerName() {<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    return serverName;<a name="line.499"></a>
-<span class="sourceLineNo">500</span>  }<a name="line.500"></a>
-<span class="sourceLineNo">501</span><a name="line.501"></a>
-<span class="sourceLineNo">502</span>  @Override<a name="line.502"></a>
-<span class="sourceLineNo">503</span>  public ChoreService getChoreService() {<a name="line.503"></a>
-<span class="sourceLineNo">504</span>    return choreService;<a name="line.504"></a>
-<span class="sourceLineNo">505</span>  }<a name="line.505"></a>
-<span class="sourceLineNo">506</span><a name="line.506"></a>
-<span class="sourceLineNo">507</span>  /** Returns Return table descriptors implementation. */<a name="line.507"></a>
-<span class="sourceLineNo">508</span>  public TableDescriptors getTableDescriptors() {<a name="line.508"></a>
-<span class="sourceLineNo">509</span>    return this.tableDescriptors;<a name="line.509"></a>
-<span class="sourceLineNo">510</span>  }<a name="line.510"></a>
-<span class="sourceLineNo">511</span><a name="line.511"></a>
-<span class="sourceLineNo">512</span>  public ExecutorService getExecutorService() {<a name="line.512"></a>
-<span class="sourceLineNo">513</span>    return executorService;<a name="line.513"></a>
-<span class="sourceLineNo">514</span>  }<a name="line.514"></a>
-<span class="sourceLineNo">515</span><a name="line.515"></a>
-<span class="sourceLineNo">516</span>  public AccessChecker getAccessChecker() {<a name="line.516"></a>
-<span class="sourceLineNo">517</span>    return rpcServices.getAccessChecker();<a name="line.517"></a>
-<span class="sourceLineNo">518</span>  }<a name="line.518"></a>
-<span class="sourceLineNo">519</span><a name="line.519"></a>
-<span class="sourceLineNo">520</span>  public ZKPermissionWatcher getZKPermissionWatcher() {<a name="line.520"></a>
-<span class="sourceLineNo">521</span>    return rpcServices.getZkPermissionWatcher();<a name="line.521"></a>
-<span class="sourceLineNo">522</span>  }<a name="line.522"></a>
-<span class="sourceLineNo">523</span><a name="line.523"></a>
-<span class="sourceLineNo">524</span>  @Override<a name="line.524"></a>
-<span class="sourceLineNo">525</span>  public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.525"></a>
-<span class="sourceLineNo">526</span>    return csm;<a name="line.526"></a>
-<span class="sourceLineNo">527</span>  }<a name="line.527"></a>
-<span class="sourceLineNo">528</span><a name="line.528"></a>
-<span class="sourceLineNo">529</span>  @Override<a name="line.529"></a>
-<span class="sourceLineNo">530</span>  public Connection createConnection(Configuration conf) throws IOException {<a name="line.530"></a>
-<span class="sourceLineNo">531</span>    User user = UserProvider.instantiate(conf).getCurrent();<a name="line.531"></a>
-<span class="sourceLineNo">532</span>    return ConnectionFactory.createConnection(conf, null, user);<a name="line.532"></a>
+<span class="sourceLineNo">497</span>  @RestrictedApi(explanation = "Should only be called in tests", link = "",<a name="line.497"></a>
+<span class="sourceLineNo">498</span>      allowedOnPath = ".*/src/test/.*")<a name="line.498"></a>
+<span class="sourceLineNo">499</span>  public boolean isShutdownHookInstalled() {<a name="line.499"></a>
+<span class="sourceLineNo">500</span>    return isShutdownHookInstalled;<a name="line.500"></a>
+<span class="sourceLineNo">501</span>  }<a name="line.501"></a>
+<span class="sourceLineNo">502</span><a name="line.502"></a>
+<span class="sourceLineNo">503</span>  @Override<a name="line.503"></a>
+<span class="sourceLineNo">504</span>  public ServerName getServerName() {<a name="line.504"></a>
+<span class="sourceLineNo">505</span>    return serverName;<a name="line.505"></a>
+<span class="sourceLineNo">506</span>  }<a name="line.506"></a>
+<span class="sourceLineNo">507</span><a name="line.507"></a>
+<span class="sourceLineNo">508</span>  @Override<a name="line.508"></a>
+<span class="sourceLineNo">509</span>  public ChoreService getChoreService() {<a name="line.509"></a>
+<span class="sourceLineNo">510</span>    return choreService;<a name="line.510"></a>
+<span class="sourceLineNo">511</span>  }<a name="line.511"></a>
+<span class="sourceLineNo">512</span><a name="line.512"></a>
+<span class="sourceLineNo">513</span>  /** Returns Return table descriptors implementation. */<a name="line.513"></a>
+<span class="sourceLineNo">514</span>  public TableDescriptors getTableDescriptors() {<a name="line.514"></a>
+<span class="sourceLineNo">515</span>    return this.tableDescriptors;<a name="line.515"></a>
+<span class="sourceLineNo">516</span>  }<a name="line.516"></a>
+<span class="sourceLineNo">517</span><a name="line.517"></a>
+<span class="sourceLineNo">518</span>  public ExecutorService getExecutorService() {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>    return executorService;<a name="line.519"></a>
+<span class="sourceLineNo">520</span>  }<a name="line.520"></a>
+<span class="sourceLineNo">521</span><a name="line.521"></a>
+<span class="sourceLineNo">522</span>  public AccessChecker getAccessChecker() {<a name="line.522"></a>
+<span class="sourceLineNo">523</span>    return rpcServices.getAccessChecker();<a name="line.523"></a>
+<span class="sourceLineNo">524</span>  }<a name="line.524"></a>
+<span class="sourceLineNo">525</span><a name="line.525"></a>
+<span class="sourceLineNo">526</span>  public ZKPermissionWatcher getZKPermissionWatcher() {<a name="line.526"></a>
+<span class="sourceLineNo">527</span>    return rpcServices.getZkPermissionWatcher();<a name="line.527"></a>
+<span class="sourceLineNo">528</span>  }<a name="line.528"></a>
+<span class="sourceLineNo">529</span><a name="line.529"></a>
+<span class="sourceLineNo">530</span>  @Override<a name="line.530"></a>
+<span class="sourceLineNo">531</span>  public CoordinatedStateManager getCoordinatedStateManager() {<a name="line.531"></a>
+<span class="sourceLineNo">532</span>    return csm;<a name="line.532"></a>
 <span class="sourceLineNo">533</span>  }<a name="line.533"></a>
 <span class="sourceLineNo">534</span><a name="line.534"></a>
-<span class="sourceLineNo">535</span>  /** Returns Return the rootDir. */<a name="line.535"></a>
-<span class="sourceLineNo">536</span>  public Path getDataRootDir() {<a name="line.536"></a>
-<span class="sourceLineNo">537</span>    return dataRootDir;<a name="line.537"></a>
-<span class="sourceLineNo">538</span>  }<a name="line.538"></a>
-<span class="sourceLineNo">539</span><a name="line.539"></a>
-<span class="sourceLineNo">540</span>  @Override<a name="line.540"></a>
-<span class="sourceLineNo">541</span>  public FileSystem getFileSystem() {<a name="line.541"></a>
-<span class="sourceLineNo">542</span>    return dataFs;<a name="line.542"></a>
-<span class="sourceLineNo">543</span>  }<a name="line.543"></a>
-<span class="sourceLineNo">544</span><a name="line.544"></a>
-<span class="sourceLineNo">545</span>  /** Returns Return the walRootDir. */<a name="line.545"></a>
-<span class="sourceLineNo">546</span>  public Path getWALRootDir() {<a name="line.546"></a>
-<span class="sourceLineNo">547</span>    return walRootDir;<a name="line.547"></a>
-<span class="sourceLineNo">548</span>  }<a name="line.548"></a>
-<span class="sourceLineNo">549</span><a name="line.549"></a>
-<span class="sourceLineNo">550</span>  /** Returns Return the walFs. */<a name="line.550"></a>
-<span class="sourceLineNo">551</span>  public FileSystem getWALFileSystem() {<a name="line.551"></a>
-<span class="sourceLineNo">552</span>    return walFs;<a name="line.552"></a>
-<span class="sourceLineNo">553</span>  }<a name="line.553"></a>
-<span class="sourceLineNo">554</span><a name="line.554"></a>
-<span class="sourceLineNo">555</span>  /** Returns True if the cluster is up. */<a name="line.555"></a>
-<span class="sourceLineNo">556</span>  public boolean isClusterUp() {<a name="line.556"></a>
-<span class="sourceLineNo">557</span>    return !clusterMode() || this.clusterStatusTracker.isClusterUp();<a name="line.557"></a>
-<span class="sourceLineNo">558</span>  }<a name="line.558"></a>
-<span class="sourceLineNo">559</span><a name="line.559"></a>
-<span class="sourceLineNo">560</span>  /** Returns time stamp in millis of when this server was started */<a name="line.560"></a>
-<span class="sourceLineNo">561</span>  public long getStartcode() {<a name="line.561"></a>
-<span class="sourceLineNo">562</span>    return this.startcode;<a name="line.562"></a>
-<span class="sourceLineNo">563</span>  }<a name="line.563"></a>
-<span class="sourceLineNo">564</span><a name="line.564"></a>
-<span class="sourceLineNo">565</span>  public InfoServer getInfoServer() {<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    return infoServer;<a name="line.566"></a>
-<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
-<span class="sourceLineNo">568</span><a name="line.568"></a>
-<span class="sourceLineNo">569</span>  public int getMsgInterval() {<a name="line.569"></a>
-<span class="sourceLineNo">570</span>    return msgInterval;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>  }<a name="line.571"></a>
-<span class="sourceLineNo">572</span><a name="line.572"></a>
-<span class="sourceLineNo">573</span>  /**<a name="line.573"></a>
-<span class="sourceLineNo">574</span>   * get NamedQueue Provider to add different logs to ringbuffer n<a name="line.574"></a>
-<span class="sourceLineNo">575</span>   */<a name="line.575"></a>
-<span class="sourceLineNo">576</span>  public NamedQueueRecorder getNamedQueueRecorder() {<a name="line.576"></a>
-<span class="sourceLineNo">577</span>    return this.namedQueueRecorder;<a name="line.577"></a>
-<span class="sourceLineNo">578</span>  }<a name="line.578"></a>
-<span class="sourceLineNo">579</span><a name="line.579"></a>
-<span class="sourceLineNo">580</span>  public RpcServerInterface getRpcServer() {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>    return rpcServices.getRpcServer();<a name="line.581"></a>
-<span class="sourceLineNo">582</span>  }<a name="line.582"></a>
-<span class="sourceLineNo">583</span><a name="line.583"></a>
-<span class="sourceLineNo">584</span>  public NettyEventLoopGroupConfig getEventLoopGroupConfig() {<a name="line.584"></a>
-<span class="sourceLineNo">585</span>    return eventLoopGroupConfig;<a name="line.585"></a>
-<span class="sourceLineNo">586</span>  }<a name="line.586"></a>
-<span class="sourceLineNo">587</span><a name="line.587"></a>
-<span class="sourceLineNo">588</span>  public R getRpcServices() {<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    return rpcServices;<a name="line.589"></a>
-<span class="sourceLineNo">590</span>  }<a name="line.590"></a>
-<span class="sourceLineNo">591</span><a name="line.591"></a>
-<span class="sourceLineNo">592</span>  @RestrictedApi(explanation = "Should only be called in tests", link = "",<a name="line.592"></a>
-<span class="sourceLineNo">593</span>      allowedOnPath = ".*/src/test/.*")<a name="line.593"></a>
-<span class="sourceLineNo">594</span>  public MetaRegionLocationCache getMetaRegionLocationCache() {<a name="line.594"></a>
-<span class="sourceLineNo">595</span>    return this.metaRegionLocationCache;<a name="line.595"></a>
+<span class="sourceLineNo">535</span>  @Override<a name="line.535"></a>
+<span class="sourceLineNo">536</span>  public Connection createConnection(Configuration conf) throws IOException {<a name="line.536"></a>
+<span class="sourceLineNo">537</span>    User user = UserProvider.instantiate(conf).getCurrent();<a name="line.537"></a>
+<span class="sourceLineNo">538</span>    return ConnectionFactory.createConnection(conf, null, user);<a name="line.538"></a>
+<span class="sourceLineNo">539</span>  }<a name="line.539"></a>
+<span class="sourceLineNo">540</span><a name="line.540"></a>
+<span class="sourceLineNo">541</span>  /** Returns Return the rootDir. */<a name="line.541"></a>
+<span class="sourceLineNo">542</span>  public Path getDataRootDir() {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>    return dataRootDir;<a name="line.543"></a>
+<span class="sourceLineNo">544</span>  }<a name="line.544"></a>
+<span class="sourceLineNo">545</span><a name="line.545"></a>
+<span class="sourceLineNo">546</span>  @Override<a name="line.546"></a>
+<span class="sourceLineNo">547</span>  public FileSystem getFileSystem() {<a name="line.547"></a>
+<span class="sourceLineNo">548</span>    return dataFs;<a name="line.548"></a>
+<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
+<span class="sourceLineNo">550</span><a name="line.550"></a>
+<span class="sourceLineNo">551</span>  /** Returns Return the walRootDir. */<a name="line.551"></a>
+<span class="sourceLineNo">552</span>  public Path getWALRootDir() {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>    return walRootDir;<a name="line.553"></a>
+<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
+<span class="sourceLineNo">555</span><a name="line.555"></a>
+<span class="sourceLineNo">556</span>  /** Returns Return the walFs. */<a name="line.556"></a>
+<span class="sourceLineNo">557</span>  public FileSystem getWALFileSystem() {<a name="line.557"></a>
+<span class="sourceLineNo">558</span>    return walFs;<a name="line.558"></a>
+<span class="sourceLineNo">559</span>  }<a name="line.559"></a>
+<span class="sourceLineNo">560</span><a name="line.560"></a>
+<span class="sourceLineNo">561</span>  /** Returns True if the cluster is up. */<a name="line.561"></a>
+<span class="sourceLineNo">562</span>  public boolean isClusterUp() {<a name="line.562"></a>
+<span class="sourceLineNo">563</span>    return !clusterMode() || this.clusterStatusTracker.isClusterUp();<a name="line.563"></a>
+<span class="sourceLineNo">564</span>  }<a name="line.564"></a>
+<span class="sourceLineNo">565</span><a name="line.565"></a>
+<span class="sourceLineNo">566</span>  /** Returns time stamp in millis of when this server was started */<a name="line.566"></a>
+<span class="sourceLineNo">567</span>  public long getStartcode() {<a name="line.567"></a>
+<span class="sourceLineNo">568</span>    return this.startcode;<a name="line.568"></a>
+<span class="sourceLineNo">569</span>  }<a name="line.569"></a>
+<span class="sourceLineNo">570</span><a name="line.570"></a>
+<span class="sourceLineNo">571</span>  public InfoServer getInfoServer() {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>    return infoServer;<a name="line.572"></a>
+<span class="sourceLineNo">573</span>  }<a name="line.573"></a>
+<span class="sourceLineNo">574</span><a name="line.574"></a>
+<span class="sourceLineNo">575</span>  public int getMsgInterval() {<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    return msgInterval;<a name="line.576"></a>
+<span class="sourceLineNo">577</span>  }<a name="line.577"></a>
+<span class="sourceLineNo">578</span><a name="line.578"></a>
+<span class="sourceLineNo">579</span>  /**<a name="line.579"></a>
+<span class="sourceLineNo">580</span>   * get NamedQueue Provider to add different logs to ringbuffer n<a name="line.580"></a>
+<span class="sourceLineNo">581</span>   */<a name="line.581"></a>
+<span class="sourceLineNo">582</span>  public NamedQueueRecorder getNamedQueueRecorder() {<a name="line.582"></a>
+<span class="sourceLineNo">583</span>    return this.namedQueueRecorder;<a name="line.583"></a>
+<span class="sourceLineNo">584</span>  }<a name="line.584"></a>
+<span class="sourceLineNo">585</span><a name="line.585"></a>
+<span class="sourceLineNo">586</span>  public RpcServerInterface getRpcServer() {<a name="line.586"></a>
+<span class="sourceLineNo">587</span>    return rpcServices.getRpcServer();<a name="line.587"></a>
+<span class="sourceLineNo">588</span>  }<a name="line.588"></a>
+<span class="sourceLineNo">589</span><a name="line.589"></a>
+<span class="sourceLineNo">590</span>  public NettyEventLoopGroupConfig getEventLoopGroupConfig() {<a name="line.590"></a>
+<span class="sourceLineNo">591</span>    return eventLoopGroupConfig;<a name="line.591"></a>
+<span class="sourceLineNo">592</span>  }<a name="line.592"></a>
+<span class="sourceLineNo">593</span><a name="line.593"></a>
+<span class="sourceLineNo">594</span>  public R getRpcServices() {<a name="line.594"></a>
+<span class="sourceLineNo">595</span>    return rpcServices;<a name="line.595"></a>
 <span class="sourceLineNo">596</span>  }<a name="line.596"></a>
 <span class="sourceLineNo">597</span><a name="line.597"></a>
-<span class="sourceLineNo">598</span>  /**<a name="line.598"></a>
-<span class="sourceLineNo">599</span>   * Reload the configuration from disk.<a name="line.599"></a>
-<span class="sourceLineNo">600</span>   */<a name="line.600"></a>
-<span class="sourceLineNo">601</span>  public void updateConfiguration() {<a name="line.601"></a>
-<span class="sourceLineNo">602</span>    LOG.info("Reloading the configuration from disk.");<a name="line.602"></a>
-<span class="sourceLineNo">603</span>    // Reload the configuration from disk.<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    conf.reloadConfiguration();<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    configurationManager.notifyAllObservers(conf);<a name="line.605"></a>
-<span class="sourceLineNo">606</span>  }<a name="line.606"></a>
-<span class="sourceLineNo">607</span><a name="line.607"></a>
-<span class="sourceLineNo">608</span>  @Override<a name="line.608"></a>
-<span class="sourceLineNo">609</span>  public String toString() {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>    return getServerName().toString();<a name="line.610"></a>
-<span class="sourceLineNo">611</span>  }<a name="line.611"></a>
-<span class="sourceLineNo">612</span><a name="line.612"></a>
-<span class="sourceLineNo">613</span>  protected abstract boolean canCreateBaseZNode();<a name="line.613"></a>
-<span class="sourceLineNo">614</span><a name="line.614"></a>
-<span class="sourceLineNo">615</span>  protected abstract String getProcessName();<a name="line.615"></a>
-<span class="sourceLineNo">616</span><a name="line.616"></a>
-<span class="sourceLineNo">617</span>  protected abstract R createRpcServices() throws IOException;<a name="line.617"></a>
+<span class="sourceLineNo">598</span>  @RestrictedApi(explanation = "Should only be called in tests", link = "",<a name="line.598"></a>
+<span class="sourceLineNo">599</span>      allowedOnPath = ".*/src/test/.*")<a name="line.599"></a>
+<span class="sourceLineNo">600</span>  public MetaRegionLocationCache getMetaRegionLocationCache() {<a name="line.600"></a>
+<span class="sourceLineNo">601</span>    return this.metaRegionLocationCache;<a name="line.601"></a>
+<span class="sourceLineNo">602</span>  }<a name="line.602"></a>
+<span class="sourceLineNo">603</span><a name="line.603"></a>
+<span class="sourceLineNo">604</span>  /**<a name="line.604"></a>
+<span class="sourceLineNo">605</span>   * Reload the configuration from disk.<a name="line.605"></a>
+<span class="sourceLineNo">606</span>   */<a name="line.606"></a>
+<span class="sourceLineNo">607</span>  public void updateConfiguration() {<a name="line.607"></a>
+<span class="sourceLineNo">608</span>    LOG.info("Reloading the configuration from disk.");<a name="line.608"></a>
+<span class="sourceLineNo">609</span>    // Reload the configuration from disk.<a name="line.609"></a>
+<span class="sourceLineNo">610</span>    conf.reloadConfiguration();<a name="line.610"></a>
+<span class="sourceLineNo">611</span>    configurationManager.notifyAllObservers(conf);<a name="line.611"></a>
+<span class="sourceLineNo">612</span>  }<a name="line.612"></a>
+<span class="sourceLineNo">613</span><a name="line.613"></a>
+<span class="sourceLineNo">614</span>  @Override<a name="line.614"></a>
+<span class="sourceLineNo">615</span>  public String toString() {<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    return getServerName().toString();<a name="line.616"></a>
+<span class="sourceLineNo">617</span>  }<a name="line.617"></a>
 <span class="sourceLineNo">618</span><a name="line.618"></a>
-<span class="sourceLineNo">619</span>  protected abstract String getUseThisHostnameInstead(Configuration conf) throws IOException;<a name="line.619"></a>
+<span class="sourceLineNo">619</span>  protected abstract boolean canCreateBaseZNode();<a name="line.619"></a>
 <span class="sourceLineNo">620</span><a name="line.620"></a>
-<span class="sourceLineNo">621</span>  protected abstract void login(UserProvider user, String host) throws IOException;<a name="line.621"></a>
+<span class="sourceLineNo">621</span>  protected abstract String getProcessName();<a name="line.621"></a>
 <span class="sourceLineNo">622</span><a name="line.622"></a>
-<span class="sourceLineNo">623</span>  protected abstract NamedQueueRecorder createNamedQueueRecord();<a name="line.623"></a>
+<span class="sourceLineNo">623</span>  protected abstract R createRpcServices() throws IOException;<a name="line.623"></a>
 <span class="sourceLineNo">624</span><a name="line.624"></a>
-<span class="sourceLineNo">625</span>  protected abstract void configureInfoServer(InfoServer infoServer);<a name="line.625"></a>
+<span class="sourceLineNo">625</span>  protected abstract String getUseThisHostnameInstead(Configuration conf) throws IOException;<a name="line.625"></a>
 <span class="sourceLineNo">626</span><a name="line.626"></a>
-<span class="sourceLineNo">627</span>  protected abstract Class&lt;? extends HttpServlet&gt; getDumpServlet();<a name="line.627"></a>
+<span class="sourceLineNo">627</span>  protected abstract void login(UserProvider user, String host) throws IOException;<a name="line.627"></a>
 <span class="sourceLineNo">628</span><a name="line.628"></a>
-<span class="sourceLineNo">629</span>  protected abstract boolean canUpdateTableDescriptor();<a name="line.629"></a>
+<span class="sourceLineNo">629</span>  protected abstract NamedQueueRecorder createNamedQueueRecord();<a name="line.629"></a>
 <span class="sourceLineNo">630</span><a name="line.630"></a>
-<span class="sourceLineNo">631</span>  protected abstract boolean cacheTableDescriptor();<a name="line.631"></a>
+<span class="sourceLineNo">631</span>  protected abstract void configureInfoServer(InfoServer infoServer);<a name="line.631"></a>
 <span class="sourceLineNo">632</span><a name="line.632"></a>
-<span class="sourceLineNo">633</span>  protected abstract boolean clusterMode();<a name="line.633"></a>
-<span class="sourceLineNo">634</span>}<a name="line.634"></a>
+<span class="sourceLineNo">633</span>  protected abstract Class&lt;? extends HttpServlet&gt; getDumpServlet();<a name="line.633"></a>
+<span class="sourceLineNo">634</span><a name="line.634"></a>
+<span class="sourceLineNo">635</span>  protected abstract boolean canUpdateTableDescriptor();<a name="line.635"></a>
+<span class="sourceLineNo">636</span><a name="line.636"></a>
+<span class="sourceLineNo">637</span>  protected abstract boolean cacheTableDescriptor();<a name="line.637"></a>
+<span class="sourceLineNo">638</span><a name="line.638"></a>
+<span class="sourceLineNo">639</span>  protected abstract boolean clusterMode();<a name="line.639"></a>
+<span class="sourceLineNo">640</span>}<a name="line.640"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.OperationStatusCode.html b/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.OperationStatusCode.html
index 5a0d8c2b2ea..9112019978f 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.OperationStatusCode.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.OperationStatusCode.html
@@ -1579,10 +1579,26 @@
 <span class="sourceLineNo">1571</span>   */<a name="line.1571"></a>
 <span class="sourceLineNo">1572</span>  public static final int BATCH_ROWS_THRESHOLD_DEFAULT = 5000;<a name="line.1572"></a>
 <span class="sourceLineNo">1573</span><a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>  private HConstants() {<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>    // Can't be instantiated with this ctor.<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>  }<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>}<a name="line.1577"></a>
+<span class="sourceLineNo">1574</span>  /**<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>   * In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>   * be able to resolve the hostname of the newly added node. If the network is interconnected, the<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>   * client can actually access the HBase cluster nodes through ip. However, since the HBase client<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>   * obtains the Master/RS address info from or the ZK or the meta table, so the Master/RS of the<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>   * HBase cluster needs to expose the service with ip instead of the hostname. Therefore, We can<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>   * use hostname by default, but at the same time, we can also provide a config to support whether<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span>   * to use ip for Master/RS service. See HBASE-27304 for details.<a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>   */<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>  public final static String HBASE_SERVER_USEIP_ENABLED_KEY = "hbase.server.useip.enabled";<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span><a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>  /**<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>   * Default value of {@link #HBASE_SERVER_USEIP_ENABLED_KEY}<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span>   */<a name="line.1587"></a>
+<span class="sourceLineNo">1588</span>  public final static boolean HBASE_SERVER_USEIP_ENABLED_DEFAULT = false;<a name="line.1588"></a>
+<span class="sourceLineNo">1589</span><a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>  private HConstants() {<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>    // Can't be instantiated with this ctor.<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>  }<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>}<a name="line.1593"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.html b/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.html
index 5a0d8c2b2ea..9112019978f 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/HConstants.html
@@ -1579,10 +1579,26 @@
 <span class="sourceLineNo">1571</span>   */<a name="line.1571"></a>
 <span class="sourceLineNo">1572</span>  public static final int BATCH_ROWS_THRESHOLD_DEFAULT = 5000;<a name="line.1572"></a>
 <span class="sourceLineNo">1573</span><a name="line.1573"></a>
-<span class="sourceLineNo">1574</span>  private HConstants() {<a name="line.1574"></a>
-<span class="sourceLineNo">1575</span>    // Can't be instantiated with this ctor.<a name="line.1575"></a>
-<span class="sourceLineNo">1576</span>  }<a name="line.1576"></a>
-<span class="sourceLineNo">1577</span>}<a name="line.1577"></a>
+<span class="sourceLineNo">1574</span>  /**<a name="line.1574"></a>
+<span class="sourceLineNo">1575</span>   * In some scenarios, such as the elastic scaling scenario on the cloud, the HBase client may not<a name="line.1575"></a>
+<span class="sourceLineNo">1576</span>   * be able to resolve the hostname of the newly added node. If the network is interconnected, the<a name="line.1576"></a>
+<span class="sourceLineNo">1577</span>   * client can actually access the HBase cluster nodes through ip. However, since the HBase client<a name="line.1577"></a>
+<span class="sourceLineNo">1578</span>   * obtains the Master/RS address info from or the ZK or the meta table, so the Master/RS of the<a name="line.1578"></a>
+<span class="sourceLineNo">1579</span>   * HBase cluster needs to expose the service with ip instead of the hostname. Therefore, We can<a name="line.1579"></a>
+<span class="sourceLineNo">1580</span>   * use hostname by default, but at the same time, we can also provide a config to support whether<a name="line.1580"></a>
+<span class="sourceLineNo">1581</span>   * to use ip for Master/RS service. See HBASE-27304 for details.<a name="line.1581"></a>
+<span class="sourceLineNo">1582</span>   */<a name="line.1582"></a>
+<span class="sourceLineNo">1583</span>  public final static String HBASE_SERVER_USEIP_ENABLED_KEY = "hbase.server.useip.enabled";<a name="line.1583"></a>
+<span class="sourceLineNo">1584</span><a name="line.1584"></a>
+<span class="sourceLineNo">1585</span>  /**<a name="line.1585"></a>
+<span class="sourceLineNo">1586</span>   * Default value of {@link #HBASE_SERVER_USEIP_ENABLED_KEY}<a name="line.1586"></a>
+<span class="sourceLineNo">1587</span>   */<a name="line.1587"></a>
+<span class="sourceLineNo">1588</span>  public final static boolean HBASE_SERVER_USEIP_ENABLED_DEFAULT = false;<a name="line.1588"></a>
+<span class="sourceLineNo">1589</span><a name="line.1589"></a>
+<span class="sourceLineNo">1590</span>  private HConstants() {<a name="line.1590"></a>
+<span class="sourceLineNo">1591</span>    // Can't be instantiated with this ctor.<a name="line.1591"></a>
+<span class="sourceLineNo">1592</span>  }<a name="line.1592"></a>
+<span class="sourceLineNo">1593</span>}<a name="line.1593"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html
index 140134dec90..89e1e0e9915 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.FlushedSequenceIdFlusher.html
@@ -227,946 +227,951 @@
 <span class="sourceLineNo">219</span>    // in, it should have been removed from serverAddressToServerInfo and queued<a name="line.219"></a>
 <span class="sourceLineNo">220</span>    // for processing by ProcessServerShutdown.<a name="line.220"></a>
 <span class="sourceLineNo">221</span><a name="line.221"></a>
-<span class="sourceLineNo">222</span>    final String hostname =<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      request.hasUseThisHostnameInstead() ? request.getUseThisHostnameInstead() : ia.getHostName();<a name="line.223"></a>
-<span class="sourceLineNo">224</span>    ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());<a name="line.224"></a>
-<span class="sourceLineNo">225</span>    checkClockSkew(sn, request.getServerCurrentTime());<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    checkIsDead(sn, "STARTUP");<a name="line.226"></a>
-<span class="sourceLineNo">227</span>    if (!checkAndRecordNewServer(sn, ServerMetricsBuilder.of(sn, versionNumber, version))) {<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      LOG.warn(<a name="line.228"></a>
-<span class="sourceLineNo">229</span>        "THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    }<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    storage.started(sn);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    return sn;<a name="line.232"></a>
-<span class="sourceLineNo">233</span>  }<a name="line.233"></a>
-<span class="sourceLineNo">234</span><a name="line.234"></a>
-<span class="sourceLineNo">235</span>  /**<a name="line.235"></a>
-<span class="sourceLineNo">236</span>   * Updates last flushed sequence Ids for the regions on server sn<a name="line.236"></a>
-<span class="sourceLineNo">237</span>   */<a name="line.237"></a>
-<span class="sourceLineNo">238</span>  private void updateLastFlushedSequenceIds(ServerName sn, ServerMetrics hsl) {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    for (Entry&lt;byte[], RegionMetrics&gt; entry : hsl.getRegionMetrics().entrySet()) {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey()));<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      long l = entry.getValue().getCompletedSequenceId();<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      // Don't let smaller sequence ids override greater sequence ids.<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      if (LOG.isTraceEnabled()) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>        LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue<a name="line.245"></a>
-<span class="sourceLineNo">246</span>          + ", completeSequenceId=" + l);<a name="line.246"></a>
-<span class="sourceLineNo">247</span>      }<a name="line.247"></a>
-<span class="sourceLineNo">248</span>      if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue)) {<a name="line.248"></a>
-<span class="sourceLineNo">249</span>        flushedSequenceIdByRegion.put(encodedRegionName, l);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>      } else if (l != HConstants.NO_SEQNUM &amp;&amp; l &lt; existingValue) {<a name="line.250"></a>
-<span class="sourceLineNo">251</span>        LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l<a name="line.251"></a>
-<span class="sourceLineNo">252</span>          + ") that is less than the previous last flushed sequence id (" + existingValue<a name="line.252"></a>
-<span class="sourceLineNo">253</span>          + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring.");<a name="line.253"></a>
-<span class="sourceLineNo">254</span>      }<a name="line.254"></a>
-<span class="sourceLineNo">255</span>      ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.256"></a>
-<span class="sourceLineNo">257</span>          () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      for (Entry&lt;byte[], Long&gt; storeSeqId : entry.getValue().getStoreSequenceId().entrySet()) {<a name="line.258"></a>
-<span class="sourceLineNo">259</span>        byte[] family = storeSeqId.getKey();<a name="line.259"></a>
-<span class="sourceLineNo">260</span>        existingValue = storeFlushedSequenceId.get(family);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>        l = storeSeqId.getValue();<a name="line.261"></a>
-<span class="sourceLineNo">262</span>        if (LOG.isTraceEnabled()) {<a name="line.262"></a>
-<span class="sourceLineNo">263</span>          LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family)<a name="line.263"></a>
-<span class="sourceLineNo">264</span>            + ", existingValue=" + existingValue + ", completeSequenceId=" + l);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>        }<a name="line.265"></a>
-<span class="sourceLineNo">266</span>        // Don't let smaller sequence ids override greater sequence ids.<a name="line.266"></a>
-<span class="sourceLineNo">267</span>        if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue.longValue())) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>          storeFlushedSequenceId.put(family, l);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        }<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    }<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>  public void regionServerReport(ServerName sn, ServerMetrics sl) throws YouAreDeadException {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>    checkIsDead(sn, "REPORT");<a name="line.275"></a>
-<span class="sourceLineNo">276</span>    if (null == this.onlineServers.replace(sn, sl)) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      // Already have this host+port combo and its just different start code?<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      // Just let the server in. Presume master joining a running cluster.<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      // recordNewServer is what happens at the end of reportServerStartup.<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      // The only thing we are skipping is passing back to the regionserver<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      // the ServerName to use. Here we presume a master has already done<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      // that so we'll press on with whatever it gave us for ServerName.<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      if (!checkAndRecordNewServer(sn, sl)) {<a name="line.283"></a>
-<span class="sourceLineNo">284</span>        LOG.info("RegionServerReport ignored, could not record the server: " + sn);<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        return; // Not recorded, so no need to move on<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      }<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    updateLastFlushedSequenceIds(sn, sl);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
-<span class="sourceLineNo">290</span><a name="line.290"></a>
-<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Check is a server of same host and port already exists, if not, or the existed one got a<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * smaller start code, record it.<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   * @param serverName the server to check and record<a name="line.294"></a>
-<span class="sourceLineNo">295</span>   * @param sl         the server load on the server<a name="line.295"></a>
-<span class="sourceLineNo">296</span>   * @return true if the server is recorded, otherwise, false<a name="line.296"></a>
-<span class="sourceLineNo">297</span>   */<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  boolean checkAndRecordNewServer(final ServerName serverName, final ServerMetrics sl) {<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    ServerName existingServer = null;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>    synchronized (this.onlineServers) {<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      existingServer = findServerWithSameHostnamePortWithLock(serverName);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      if (existingServer != null &amp;&amp; (existingServer.getStartcode() &gt; serverName.getStartcode())) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>        LOG.info("Server serverName=" + serverName + " rejected; we already have "<a name="line.303"></a>
-<span class="sourceLineNo">304</span>          + existingServer.toString() + " registered with same hostname and port");<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        return false;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>      recordNewServerWithLock(serverName, sl);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
-<span class="sourceLineNo">309</span><a name="line.309"></a>
-<span class="sourceLineNo">310</span>    // Tell our listeners that a server was added<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    if (!this.listeners.isEmpty()) {<a name="line.311"></a>
-<span class="sourceLineNo">312</span>      for (ServerListener listener : this.listeners) {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>        listener.serverAdded(serverName);<a name="line.313"></a>
-<span class="sourceLineNo">314</span>      }<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    }<a name="line.315"></a>
-<span class="sourceLineNo">316</span><a name="line.316"></a>
-<span class="sourceLineNo">317</span>    // Note that we assume that same ts means same server, and don't expire in that case.<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    // TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    if (existingServer != null &amp;&amp; (existingServer.getStartcode() &lt; serverName.getStartcode())) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      LOG.info("Triggering server recovery; existingServer " + existingServer<a name="line.320"></a>
-<span class="sourceLineNo">321</span>        + " looks stale, new server:" + serverName);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      expireServer(existingServer);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    return true;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>  }<a name="line.325"></a>
-<span class="sourceLineNo">326</span><a name="line.326"></a>
-<span class="sourceLineNo">327</span>  /**<a name="line.327"></a>
-<span class="sourceLineNo">328</span>   * Find out the region servers crashed between the crash of the previous master instance and the<a name="line.328"></a>
-<span class="sourceLineNo">329</span>   * current master instance and schedule SCP for them.<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * &lt;p/&gt;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * Since the {@code RegionServerTracker} has already helped us to construct the online servers set<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   * by scanning zookeeper, now we can compare the online servers with {@code liveServersFromWALDir}<a name="line.332"></a>
-<span class="sourceLineNo">333</span>   * to find out whether there are servers which are already dead.<a name="line.333"></a>
-<span class="sourceLineNo">334</span>   * &lt;p/&gt;<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * Must be called inside the initialization method of {@code RegionServerTracker} to avoid<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * concurrency issue.<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   * @param deadServersFromPE     the region servers which already have a SCP associated.<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param liveServersFromWALDir the live region servers from wal directory.<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   */<a name="line.339"></a>
-<span class="sourceLineNo">340</span>  void findDeadServersAndProcess(Set&lt;ServerName&gt; deadServersFromPE,<a name="line.340"></a>
-<span class="sourceLineNo">341</span>    Set&lt;ServerName&gt; liveServersFromWALDir) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    deadServersFromPE.forEach(deadservers::putIfAbsent);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    liveServersFromWALDir.stream().filter(sn -&gt; !onlineServers.containsKey(sn))<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      .forEach(this::expireServer);<a name="line.344"></a>
-<span class="sourceLineNo">345</span>  }<a name="line.345"></a>
-<span class="sourceLineNo">346</span><a name="line.346"></a>
-<span class="sourceLineNo">347</span>  /**<a name="line.347"></a>
-<span class="sourceLineNo">348</span>   * Checks if the clock skew between the server and the master. If the clock skew exceeds the<a name="line.348"></a>
-<span class="sourceLineNo">349</span>   * configured max, it will throw an exception; if it exceeds the configured warning threshold, it<a name="line.349"></a>
-<span class="sourceLineNo">350</span>   * will log a warning but start normally.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>   * @param serverName Incoming servers's name n * @throws ClockOutOfSyncException if the skew<a name="line.351"></a>
-<span class="sourceLineNo">352</span>   *                   exceeds the configured max value<a name="line.352"></a>
-<span class="sourceLineNo">353</span>   */<a name="line.353"></a>
-<span class="sourceLineNo">354</span>  private void checkClockSkew(final ServerName serverName, final long serverCurrentTime)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>    throws ClockOutOfSyncException {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    long skew = Math.abs(EnvironmentEdgeManager.currentTime() - serverCurrentTime);<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    if (skew &gt; maxSkew) {<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      String message = "Server " + serverName + " has been "<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        + "rejected; Reported time is too far out of sync with master.  " + "Time difference of "<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        + skew + "ms &gt; max allowed of " + maxSkew + "ms";<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      LOG.warn(message);<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      throw new ClockOutOfSyncException(message);<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    } else if (skew &gt; warningSkew) {<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      String message = "Reported time for server " + serverName + " is out of sync with master "<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        + "by " + skew + "ms. (Warning threshold is " + warningSkew + "ms; " + "error threshold is "<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        + maxSkew + "ms)";<a name="line.366"></a>
-<span class="sourceLineNo">367</span>      LOG.warn(message);<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  }<a name="line.369"></a>
-<span class="sourceLineNo">370</span><a name="line.370"></a>
-<span class="sourceLineNo">371</span>  /**<a name="line.371"></a>
-<span class="sourceLineNo">372</span>   * Called when RegionServer first reports in for duty and thereafter each time it heartbeats to<a name="line.372"></a>
-<span class="sourceLineNo">373</span>   * make sure it is has not been figured for dead. If this server is on the dead list, reject it<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * with a YouAreDeadException. If it was dead but came back with a new start code, remove the old<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * entry from the dead list.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   * @param what START or REPORT<a name="line.376"></a>
-<span class="sourceLineNo">377</span>   */<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  private void checkIsDead(final ServerName serverName, final String what)<a name="line.378"></a>
-<span class="sourceLineNo">379</span>    throws YouAreDeadException {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>      // Exact match: host name, port and start code all match with existing one of the<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      // dead servers. So, this server must be dead. Tell it to kill itself.<a name="line.382"></a>
-<span class="sourceLineNo">383</span>      String message =<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        "Server " + what + " rejected; currently processing " + serverName + " as dead server";<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      LOG.debug(message);<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      throw new YouAreDeadException(message);<a name="line.386"></a>
-<span class="sourceLineNo">387</span>    }<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    // Remove dead server with same hostname and port of newly checking in rs after master<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    // initialization. See HBASE-5916 for more information.<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    if (<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      (this.master == null || this.master.isInitialized())<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        &amp;&amp; this.deadservers.cleanPreviousInstance(serverName)<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    ) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      // This server has now become alive after we marked it as dead.<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      // We removed it's previous entry from the dead list to reflect it.<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      LOG.debug("{} {} came back up, removed it from the dead servers list", what, serverName);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>  }<a name="line.398"></a>
-<span class="sourceLineNo">399</span><a name="line.399"></a>
-<span class="sourceLineNo">400</span>  /**<a name="line.400"></a>
-<span class="sourceLineNo">401</span>   * Assumes onlineServers is locked.<a name="line.401"></a>
-<span class="sourceLineNo">402</span>   * @return ServerName with matching hostname and port.<a name="line.402"></a>
-<span class="sourceLineNo">403</span>   */<a name="line.403"></a>
-<span class="sourceLineNo">404</span>  private ServerName findServerWithSameHostnamePortWithLock(final ServerName serverName) {<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    ServerName end =<a name="line.405"></a>
-<span class="sourceLineNo">406</span>      ServerName.valueOf(serverName.getHostname(), serverName.getPort(), Long.MAX_VALUE);<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    ServerName r = onlineServers.lowerKey(end);<a name="line.408"></a>
-<span class="sourceLineNo">409</span>    if (r != null) {<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      if (ServerName.isSameAddress(r, serverName)) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>        return r;<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      }<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    }<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    return null;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>  }<a name="line.415"></a>
-<span class="sourceLineNo">416</span><a name="line.416"></a>
-<span class="sourceLineNo">417</span>  /**<a name="line.417"></a>
-<span class="sourceLineNo">418</span>   * Adds the onlineServers list. onlineServers should be locked.<a name="line.418"></a>
-<span class="sourceLineNo">419</span>   * @param serverName The remote servers name.<a name="line.419"></a>
-<span class="sourceLineNo">420</span>   */<a name="line.420"></a>
-<span class="sourceLineNo">421</span>  void recordNewServerWithLock(final ServerName serverName, final ServerMetrics sl) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    LOG.info("Registering regionserver=" + serverName);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>    this.onlineServers.put(serverName, sl);<a name="line.423"></a>
-<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
-<span class="sourceLineNo">425</span><a name="line.425"></a>
-<span class="sourceLineNo">426</span>  public ConcurrentNavigableMap&lt;byte[], Long&gt; getFlushedSequenceIdByRegion() {<a name="line.426"></a>
-<span class="sourceLineNo">427</span>    return flushedSequenceIdByRegion;<a name="line.427"></a>
-<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
-<span class="sourceLineNo">429</span><a name="line.429"></a>
-<span class="sourceLineNo">430</span>  public RegionStoreSequenceIds getLastFlushedSequenceId(byte[] encodedRegionName) {<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    RegionStoreSequenceIds.Builder builder = RegionStoreSequenceIds.newBuilder();<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    Long seqId = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    builder.setLastFlushedSequenceId(seqId != null ? seqId.longValue() : HConstants.NO_SEQNUM);<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    Map&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      storeFlushedSequenceIdsByRegion.get(encodedRegionName);<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    if (storeFlushedSequenceId != null) {<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      for (Map.Entry&lt;byte[], Long&gt; entry : storeFlushedSequenceId.entrySet()) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>        builder.addStoreSequenceId(StoreSequenceId.newBuilder()<a name="line.438"></a>
-<span class="sourceLineNo">439</span>          .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey()))<a name="line.439"></a>
-<span class="sourceLineNo">440</span>          .setSequenceId(entry.getValue().longValue()).build());<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      }<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    }<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    return builder.build();<a name="line.443"></a>
-<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>  /**<a name="line.446"></a>
-<span class="sourceLineNo">447</span>   * n * @return ServerMetrics if serverName is known else null<a name="line.447"></a>
-<span class="sourceLineNo">448</span>   */<a name="line.448"></a>
-<span class="sourceLineNo">449</span>  public ServerMetrics getLoad(final ServerName serverName) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    return this.onlineServers.get(serverName);<a name="line.450"></a>
-<span class="sourceLineNo">451</span>  }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>  /**<a name="line.453"></a>
-<span class="sourceLineNo">454</span>   * Compute the average load across all region servers. Currently, this uses a very naive<a name="line.454"></a>
-<span class="sourceLineNo">455</span>   * computation - just uses the number of regions being served, ignoring stats about number of<a name="line.455"></a>
-<span class="sourceLineNo">456</span>   * requests.<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * @return the average load<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   */<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  public double getAverageLoad() {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    int totalLoad = 0;<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    int numServers = 0;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    for (ServerMetrics sl : this.onlineServers.values()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>      numServers++;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>      totalLoad += sl.getRegionMetrics().size();<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    return numServers == 0 ? 0 : (double) totalLoad / (double) numServers;<a name="line.466"></a>
-<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
-<span class="sourceLineNo">468</span><a name="line.468"></a>
-<span class="sourceLineNo">469</span>  /** Returns the count of active regionservers */<a name="line.469"></a>
-<span class="sourceLineNo">470</span>  public int countOfRegionServers() {<a name="line.470"></a>
-<span class="sourceLineNo">471</span>    // Presumes onlineServers is a concurrent map<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    return this.onlineServers.size();<a name="line.472"></a>
-<span class="sourceLineNo">473</span>  }<a name="line.473"></a>
-<span class="sourceLineNo">474</span><a name="line.474"></a>
-<span class="sourceLineNo">475</span>  /** Returns Read-only map of servers to serverinfo */<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  public Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    // Presumption is that iterating the returned Map is OK.<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    synchronized (this.onlineServers) {<a name="line.478"></a>
-<span class="sourceLineNo">479</span>      return Collections.unmodifiableMap(this.onlineServers);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
-<span class="sourceLineNo">482</span><a name="line.482"></a>
-<span class="sourceLineNo">483</span>  public DeadServer getDeadServers() {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return this.deadservers;<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  /**<a name="line.487"></a>
-<span class="sourceLineNo">488</span>   * Checks if any dead servers are currently in progress.<a name="line.488"></a>
-<span class="sourceLineNo">489</span>   * @return true if any RS are being processed as dead, false if not<a name="line.489"></a>
-<span class="sourceLineNo">490</span>   */<a name="line.490"></a>
-<span class="sourceLineNo">491</span>  public boolean areDeadServersInProgress() throws IOException {<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return master.getProcedures().stream()<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      .anyMatch(p -&gt; !p.isFinished() &amp;&amp; p instanceof ServerCrashProcedure);<a name="line.493"></a>
-<span class="sourceLineNo">494</span>  }<a name="line.494"></a>
-<span class="sourceLineNo">495</span><a name="line.495"></a>
-<span class="sourceLineNo">496</span>  void letRegionServersShutdown() {<a name="line.496"></a>
-<span class="sourceLineNo">497</span>    long previousLogTime = 0;<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    ServerName sn = master.getServerName();<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    ZKWatcher zkw = master.getZooKeeper();<a name="line.499"></a>
-<span class="sourceLineNo">500</span>    int onlineServersCt;<a name="line.500"></a>
-<span class="sourceLineNo">501</span>    while ((onlineServersCt = onlineServers.size()) &gt; 0) {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        Set&lt;ServerName&gt; remainingServers = onlineServers.keySet();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        synchronized (onlineServers) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          if (remainingServers.size() == 1 &amp;&amp; remainingServers.contains(sn)) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>            // Master will delete itself later.<a name="line.506"></a>
-<span class="sourceLineNo">507</span>            return;<a name="line.507"></a>
-<span class="sourceLineNo">508</span>          }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>        }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        StringBuilder sb = new StringBuilder();<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        // It's ok here to not sync on onlineServers - merely logging<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        for (ServerName key : remainingServers) {<a name="line.512"></a>
-<span class="sourceLineNo">513</span>          if (sb.length() &gt; 0) {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>            sb.append(", ");<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          }<a name="line.515"></a>
-<span class="sourceLineNo">516</span>          sb.append(key);<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        LOG.info("Waiting on regionserver(s) " + sb.toString());<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        previousLogTime = EnvironmentEdgeManager.currentTime();<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span><a name="line.521"></a>
-<span class="sourceLineNo">522</span>      try {<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        List&lt;String&gt; servers = getRegionServersInZK(zkw);<a name="line.523"></a>
-<span class="sourceLineNo">524</span>        if (<a name="line.524"></a>
-<span class="sourceLineNo">525</span>          servers == null || servers.isEmpty()<a name="line.525"></a>
-<span class="sourceLineNo">526</span>            || (servers.size() == 1 &amp;&amp; servers.contains(sn.toString()))<a name="line.526"></a>
-<span class="sourceLineNo">527</span>        ) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          LOG.info("ZK shows there is only the master self online, exiting now");<a name="line.528"></a>
-<span class="sourceLineNo">529</span>          // Master could have lost some ZK events, no need to wait more.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          break;<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      } catch (KeeperException ke) {<a name="line.532"></a>
-<span class="sourceLineNo">533</span>        LOG.warn("Failed to list regionservers", ke);<a name="line.533"></a>
-<span class="sourceLineNo">534</span>        // ZK is malfunctioning, don't hang here<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        break;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      }<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      synchronized (onlineServers) {<a name="line.537"></a>
-<span class="sourceLineNo">538</span>        try {<a name="line.538"></a>
-<span class="sourceLineNo">539</span>          if (onlineServersCt == onlineServers.size()) onlineServers.wait(100);<a name="line.539"></a>
-<span class="sourceLineNo">540</span>        } catch (InterruptedException ignored) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>          // continue<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        }<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
-<span class="sourceLineNo">545</span>  }<a name="line.545"></a>
-<span class="sourceLineNo">546</span><a name="line.546"></a>
-<span class="sourceLineNo">547</span>  private List&lt;String&gt; getRegionServersInZK(final ZKWatcher zkw) throws KeeperException {<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    return ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>  /**<a name="line.551"></a>
-<span class="sourceLineNo">552</span>   * Expire the passed server. Add it to list of dead servers and queue a shutdown processing.<a name="line.552"></a>
-<span class="sourceLineNo">553</span>   * @return pid if we queued a ServerCrashProcedure else {@link Procedure#NO_PROC_ID} if we did not<a name="line.553"></a>
-<span class="sourceLineNo">554</span>   *         (could happen for many reasons including the fact that its this server that is going<a name="line.554"></a>
-<span class="sourceLineNo">555</span>   *         down or we already have queued an SCP for this server or SCP processing is currently<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   *         disabled because we are in startup phase).<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   */<a name="line.557"></a>
-<span class="sourceLineNo">558</span>  // Redo test so we can make this protected.<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  public synchronized long expireServer(final ServerName serverName) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return expireServer(serverName, false);<a name="line.560"></a>
-<span class="sourceLineNo">561</span><a name="line.561"></a>
-<span class="sourceLineNo">562</span>  }<a name="line.562"></a>
-<span class="sourceLineNo">563</span><a name="line.563"></a>
-<span class="sourceLineNo">564</span>  synchronized long expireServer(final ServerName serverName, boolean force) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    // THIS server is going down... can't handle our own expiration.<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    if (serverName.equals(master.getServerName())) {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>      if (!(master.isAborted() || master.isStopped())) {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>        master.stop("We lost our znode?");<a name="line.568"></a>
-<span class="sourceLineNo">569</span>      }<a name="line.569"></a>
-<span class="sourceLineNo">570</span>      return Procedure.NO_PROC_ID;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>    }<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.572"></a>
-<span class="sourceLineNo">573</span>      LOG.warn("Expiration called on {} but already in DeadServer", serverName);<a name="line.573"></a>
-<span class="sourceLineNo">574</span>      return Procedure.NO_PROC_ID;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    moveFromOnlineToDeadServers(serverName);<a name="line.576"></a>
-<span class="sourceLineNo">577</span><a name="line.577"></a>
-<span class="sourceLineNo">578</span>    // If server is in draining mode, remove corresponding znode<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    // In some tests, the mocked HM may not have ZK Instance, hence null check<a name="line.579"></a>
-<span class="sourceLineNo">580</span>    if (master.getZooKeeper() != null) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>      String drainingZnode = ZNodePaths<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        .joinZNode(master.getZooKeeper().getZNodePaths().drainingZNode, serverName.getServerName());<a name="line.582"></a>
-<span class="sourceLineNo">583</span>      try {<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        ZKUtil.deleteNodeFailSilent(master.getZooKeeper(), drainingZnode);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>      } catch (KeeperException e) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        LOG.warn(<a name="line.586"></a>
-<span class="sourceLineNo">587</span>          "Error deleting the draining znode for stopping server " + serverName.getServerName(), e);<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      }<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    }<a name="line.589"></a>
-<span class="sourceLineNo">590</span><a name="line.590"></a>
-<span class="sourceLineNo">591</span>    // If cluster is going down, yes, servers are going to be expiring; don't<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    // process as a dead server<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (isClusterShutdown()) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      LOG.info("Cluster shutdown set; " + serverName + " expired; onlineServers="<a name="line.594"></a>
-<span class="sourceLineNo">595</span>        + this.onlineServers.size());<a name="line.595"></a>
-<span class="sourceLineNo">596</span>      if (this.onlineServers.isEmpty()) {<a name="line.596"></a>
-<span class="sourceLineNo">597</span>        master.stop("Cluster shutdown set; onlineServer=0");<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      }<a name="line.598"></a>
-<span class="sourceLineNo">599</span>      return Procedure.NO_PROC_ID;<a name="line.599"></a>
-<span class="sourceLineNo">600</span>    }<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    LOG.info("Processing expiration of " + serverName + " on " + this.master.getServerName());<a name="line.601"></a>
-<span class="sourceLineNo">602</span>    long pid = master.getAssignmentManager().submitServerCrash(serverName, true, force);<a name="line.602"></a>
-<span class="sourceLineNo">603</span>    storage.expired(serverName);<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    // Tell our listeners that a server was removed<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    if (!this.listeners.isEmpty()) {<a name="line.605"></a>
-<span class="sourceLineNo">606</span>      this.listeners.stream().forEach(l -&gt; l.serverRemoved(serverName));<a name="line.606"></a>
-<span class="sourceLineNo">607</span>    }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    // trigger a persist of flushedSeqId<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    if (flushedSeqIdFlusher != null) {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>      flushedSeqIdFlusher.triggerNow();<a name="line.610"></a>
-<span class="sourceLineNo">611</span>    }<a name="line.611"></a>
-<span class="sourceLineNo">612</span>    return pid;<a name="line.612"></a>
-<span class="sourceLineNo">613</span>  }<a name="line.613"></a>
-<span class="sourceLineNo">614</span><a name="line.614"></a>
-<span class="sourceLineNo">615</span>  /**<a name="line.615"></a>
-<span class="sourceLineNo">616</span>   * Called when server has expired.<a name="line.616"></a>
-<span class="sourceLineNo">617</span>   */<a name="line.617"></a>
-<span class="sourceLineNo">618</span>  // Locking in this class needs cleanup.<a name="line.618"></a>
-<span class="sourceLineNo">619</span>  public synchronized void moveFromOnlineToDeadServers(final ServerName sn) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    synchronized (this.onlineServers) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      boolean online = this.onlineServers.containsKey(sn);<a name="line.621"></a>
-<span class="sourceLineNo">622</span>      if (online) {<a name="line.622"></a>
-<span class="sourceLineNo">623</span>        // Remove the server from the known servers lists and update load info BUT<a name="line.623"></a>
-<span class="sourceLineNo">624</span>        // add to deadservers first; do this so it'll show in dead servers list if<a name="line.624"></a>
-<span class="sourceLineNo">625</span>        // not in online servers list.<a name="line.625"></a>
-<span class="sourceLineNo">626</span>        this.deadservers.putIfAbsent(sn);<a name="line.626"></a>
-<span class="sourceLineNo">627</span>        this.onlineServers.remove(sn);<a name="line.627"></a>
-<span class="sourceLineNo">628</span>        onlineServers.notifyAll();<a name="line.628"></a>
-<span class="sourceLineNo">629</span>      } else {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>        // If not online, that is odd but may happen if 'Unknown Servers' -- where meta<a name="line.630"></a>
-<span class="sourceLineNo">631</span>        // has references to servers not online nor in dead servers list. If<a name="line.631"></a>
-<span class="sourceLineNo">632</span>        // 'Unknown Server', don't add to DeadServers else will be there for ever.<a name="line.632"></a>
-<span class="sourceLineNo">633</span>        LOG.trace("Expiration of {} but server not online", sn);<a name="line.633"></a>
-<span class="sourceLineNo">634</span>      }<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    }<a name="line.635"></a>
-<span class="sourceLineNo">636</span>  }<a name="line.636"></a>
-<span class="sourceLineNo">637</span><a name="line.637"></a>
-<span class="sourceLineNo">638</span>  /*<a name="line.638"></a>
-<span class="sourceLineNo">639</span>   * Remove the server from the drain list.<a name="line.639"></a>
-<span class="sourceLineNo">640</span>   */<a name="line.640"></a>
-<span class="sourceLineNo">641</span>  public synchronized boolean removeServerFromDrainList(final ServerName sn) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.642"></a>
-<span class="sourceLineNo">643</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.643"></a>
-<span class="sourceLineNo">644</span><a name="line.644"></a>
-<span class="sourceLineNo">645</span>    if (!this.isServerOnline(sn)) {<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.646"></a>
-<span class="sourceLineNo">647</span>        + "Removing from draining list anyway, as requested.");<a name="line.647"></a>
-<span class="sourceLineNo">648</span>    }<a name="line.648"></a>
-<span class="sourceLineNo">649</span>    // Remove the server from the draining servers lists.<a name="line.649"></a>
-<span class="sourceLineNo">650</span>    return this.drainingServers.remove(sn);<a name="line.650"></a>
-<span class="sourceLineNo">651</span>  }<a name="line.651"></a>
-<span class="sourceLineNo">652</span><a name="line.652"></a>
-<span class="sourceLineNo">653</span>  /**<a name="line.653"></a>
-<span class="sourceLineNo">654</span>   * Add the server to the drain list. n * @return True if the server is added or the server is<a name="line.654"></a>
-<span class="sourceLineNo">655</span>   * already on the drain list.<a name="line.655"></a>
-<span class="sourceLineNo">656</span>   */<a name="line.656"></a>
-<span class="sourceLineNo">657</span>  public synchronized boolean addServerToDrainList(final ServerName sn) {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.659"></a>
-<span class="sourceLineNo">660</span><a name="line.660"></a>
-<span class="sourceLineNo">661</span>    if (!this.isServerOnline(sn)) {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.662"></a>
-<span class="sourceLineNo">663</span>        + "Ignoring request to add it to draining list.");<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      return false;<a name="line.664"></a>
-<span class="sourceLineNo">665</span>    }<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    // Add the server to the draining servers lists, if it's not already in<a name="line.666"></a>
-<span class="sourceLineNo">667</span>    // it.<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    if (this.drainingServers.contains(sn)) {<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      LOG.warn("Server " + sn + " is already in the draining server list."<a name="line.669"></a>
-<span class="sourceLineNo">670</span>        + "Ignoring request to add it again.");<a name="line.670"></a>
-<span class="sourceLineNo">671</span>      return true;<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    }<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    LOG.info("Server " + sn + " added to draining server list.");<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    return this.drainingServers.add(sn);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>  }<a name="line.675"></a>
-<span class="sourceLineNo">676</span><a name="line.676"></a>
-<span class="sourceLineNo">677</span>  /**<a name="line.677"></a>
-<span class="sourceLineNo">678</span>   * Contacts a region server and waits up to timeout ms to close the region. This bypasses the<a name="line.678"></a>
-<span class="sourceLineNo">679</span>   * active hmaster. Pass -1 as timeout if you do not want to wait on result.<a name="line.679"></a>
-<span class="sourceLineNo">680</span>   */<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  public static void closeRegionSilentlyAndWait(AsyncClusterConnection connection,<a name="line.681"></a>
-<span class="sourceLineNo">682</span>    ServerName server, RegionInfo region, long timeout) throws IOException, InterruptedException {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    AsyncRegionServerAdmin admin = connection.getRegionServerAdmin(server);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>    try {<a name="line.684"></a>
-<span class="sourceLineNo">685</span>      FutureUtils.get(<a name="line.685"></a>
-<span class="sourceLineNo">686</span>        admin.closeRegion(ProtobufUtil.buildCloseRegionRequest(server, region.getRegionName())));<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    } catch (IOException e) {<a name="line.687"></a>
-<span class="sourceLineNo">688</span>      LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    }<a name="line.689"></a>
-<span class="sourceLineNo">690</span>    if (timeout &lt; 0) {<a name="line.690"></a>
-<span class="sourceLineNo">691</span>      return;<a name="line.691"></a>
-<span class="sourceLineNo">692</span>    }<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    long expiration = timeout + EnvironmentEdgeManager.currentTime();<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    while (EnvironmentEdgeManager.currentTime() &lt; expiration) {<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      try {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>        RegionInfo rsRegion = ProtobufUtil.toRegionInfo(FutureUtils<a name="line.696"></a>
-<span class="sourceLineNo">697</span>          .get(<a name="line.697"></a>
-<span class="sourceLineNo">698</span>            admin.getRegionInfo(RequestConverter.buildGetRegionInfoRequest(region.getRegionName())))<a name="line.698"></a>
-<span class="sourceLineNo">699</span>          .getRegionInfo());<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        if (rsRegion == null) {<a name="line.700"></a>
-<span class="sourceLineNo">701</span>          return;<a name="line.701"></a>
-<span class="sourceLineNo">702</span>        }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      } catch (IOException ioe) {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>        if (<a name="line.704"></a>
-<span class="sourceLineNo">705</span>          ioe instanceof NotServingRegionException<a name="line.705"></a>
-<span class="sourceLineNo">706</span>            || (ioe instanceof RemoteWithExtrasException &amp;&amp; ((RemoteWithExtrasException) ioe)<a name="line.706"></a>
-<span class="sourceLineNo">707</span>              .unwrapRemoteException() instanceof NotServingRegionException)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>        ) {<a name="line.708"></a>
-<span class="sourceLineNo">709</span>          // no need to retry again<a name="line.709"></a>
-<span class="sourceLineNo">710</span>          return;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>        }<a name="line.711"></a>
-<span class="sourceLineNo">712</span>        LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(),<a name="line.712"></a>
-<span class="sourceLineNo">713</span>          ioe);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      }<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      Thread.sleep(1000);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    }<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>  }<a name="line.718"></a>
-<span class="sourceLineNo">719</span><a name="line.719"></a>
-<span class="sourceLineNo">720</span>  /**<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   * Calculate min necessary to start. This is not an absolute. It is just a friction that will<a name="line.721"></a>
-<span class="sourceLineNo">722</span>   * cause us hang around a bit longer waiting on RegionServers to check-in.<a name="line.722"></a>
-<span class="sourceLineNo">723</span>   */<a name="line.723"></a>
-<span class="sourceLineNo">724</span>  private int getMinToStart() {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    if (master.isInMaintenanceMode()) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      // If in maintenance mode, then in process region server hosting meta will be the only server<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      // available<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      return 1;<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    }<a name="line.729"></a>
-<span class="sourceLineNo">730</span><a name="line.730"></a>
-<span class="sourceLineNo">731</span>    int minimumRequired = 1;<a name="line.731"></a>
-<span class="sourceLineNo">732</span>    int minToStart = this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MINTOSTART, -1);<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    // Ensure we are never less than minimumRequired else stuff won't work.<a name="line.733"></a>
-<span class="sourceLineNo">734</span>    return Math.max(minToStart, minimumRequired);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  }<a name="line.735"></a>
-<span class="sourceLineNo">736</span><a name="line.736"></a>
-<span class="sourceLineNo">737</span>  /**<a name="line.737"></a>
-<span class="sourceLineNo">738</span>   * Wait for the region servers to report in. We will wait until one of this condition is met: -<a name="line.738"></a>
-<span class="sourceLineNo">739</span>   * the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region<a name="line.739"></a>
-<span class="sourceLineNo">740</span>   * servers is reached - the 'hbase.master.wait.on.regionservers.mintostart' is reached AND there<a name="line.740"></a>
-<span class="sourceLineNo">741</span>   * have been no new region server in for 'hbase.master.wait.on.regionservers.interval' time AND<a name="line.741"></a>
-<span class="sourceLineNo">742</span>   * the 'hbase.master.wait.on.regionservers.timeout' is reached n<a name="line.742"></a>
-<span class="sourceLineNo">743</span>   */<a name="line.743"></a>
-<span class="sourceLineNo">744</span>  public void waitForRegionServers(MonitoredTask status) throws InterruptedException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    final long interval =<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_INTERVAL, 1500);<a name="line.746"></a>
-<span class="sourceLineNo">747</span>    final long timeout =<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_TIMEOUT, 4500);<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    // Min is not an absolute; just a friction making us wait longer on server checkin.<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    int minToStart = getMinToStart();<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    int maxToStart =<a name="line.751"></a>
-<span class="sourceLineNo">752</span>      this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MAXTOSTART, Integer.MAX_VALUE);<a name="line.752"></a>
-<span class="sourceLineNo">753</span>    if (maxToStart &lt; minToStart) {<a name="line.753"></a>
-<span class="sourceLineNo">754</span>      LOG.warn(String.format("The value of '%s' (%d) is set less than '%s' (%d), ignoring.",<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        WAIT_ON_REGIONSERVERS_MAXTOSTART, maxToStart, WAIT_ON_REGIONSERVERS_MINTOSTART,<a name="line.755"></a>
-<span class="sourceLineNo">756</span>        minToStart));<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      maxToStart = Integer.MAX_VALUE;<a name="line.757"></a>
-<span class="sourceLineNo">758</span>    }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>    long now = EnvironmentEdgeManager.currentTime();<a name="line.760"></a>
-<span class="sourceLineNo">761</span>    final long startTime = now;<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    long slept = 0;<a name="line.762"></a>
-<span class="sourceLineNo">763</span>    long lastLogTime = 0;<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    long lastCountChange = startTime;<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    int count = countOfRegionServers();<a name="line.765"></a>
-<span class="sourceLineNo">766</span>    int oldCount = 0;<a name="line.766"></a>
-<span class="sourceLineNo">767</span>    // This while test is a little hard to read. We try to comment it in below but in essence:<a name="line.767"></a>
-<span class="sourceLineNo">768</span>    // Wait if Master is not stopped and the number of regionservers that have checked-in is<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    // less than the maxToStart. Both of these conditions will be true near universally.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>    // Next, we will keep cycling if ANY of the following three conditions are true:<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    // 1. The time since a regionserver registered is &lt; interval (means servers are actively<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    // checking in).<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    // 2. We are under the total timeout.<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    // 3. The count of servers is &lt; minimum.<a name="line.774"></a>
-<span class="sourceLineNo">775</span>    for (ServerListener listener : this.listeners) {<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      listener.waiting();<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    while (<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      !this.master.isStopped() &amp;&amp; !isClusterShutdown() &amp;&amp; count &lt; maxToStart<a name="line.779"></a>
-<span class="sourceLineNo">780</span>        &amp;&amp; ((lastCountChange + interval) &gt; now || timeout &gt; slept || count &lt; minToStart)<a name="line.780"></a>
-<span class="sourceLineNo">781</span>    ) {<a name="line.781"></a>
-<span class="sourceLineNo">782</span>      // Log some info at every interval time or if there is a change<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      if (oldCount != count || lastLogTime + interval &lt; now) {<a name="line.783"></a>
-<span class="sourceLineNo">784</span>        lastLogTime = now;<a name="line.784"></a>
-<span class="sourceLineNo">785</span>        String msg =<a name="line.785"></a>
-<span class="sourceLineNo">786</span>          "Waiting on regionserver count=" + count + "; waited=" + slept + "ms, expecting min="<a name="line.786"></a>
-<span class="sourceLineNo">787</span>            + minToStart + " server(s), max=" + getStrForMax(maxToStart) + " server(s), "<a name="line.787"></a>
-<span class="sourceLineNo">788</span>            + "timeout=" + timeout + "ms, lastChange=" + (now - lastCountChange) + "ms";<a name="line.788"></a>
-<span class="sourceLineNo">789</span>        LOG.info(msg);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        status.setStatus(msg);<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span><a name="line.792"></a>
-<span class="sourceLineNo">793</span>      // We sleep for some time<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      final long sleepTime = 50;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>      Thread.sleep(sleepTime);<a name="line.795"></a>
-<span class="sourceLineNo">796</span>      now = EnvironmentEdgeManager.currentTime();<a name="line.796"></a>
-<span class="sourceLineNo">797</span>      slept = now - startTime;<a name="line.797"></a>
-<span class="sourceLineNo">798</span><a name="line.798"></a>
-<span class="sourceLineNo">799</span>      oldCount = count;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>      count = countOfRegionServers();<a name="line.800"></a>
-<span class="sourceLineNo">801</span>      if (count != oldCount) {<a name="line.801"></a>
-<span class="sourceLineNo">802</span>        lastCountChange = now;<a name="line.802"></a>
-<span class="sourceLineNo">803</span>      }<a name="line.803"></a>
-<span class="sourceLineNo">804</span>    }<a name="line.804"></a>
-<span class="sourceLineNo">805</span>    // Did we exit the loop because cluster is going down?<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    if (isClusterShutdown()) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>      this.master.stop("Cluster shutdown");<a name="line.807"></a>
-<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
-<span class="sourceLineNo">809</span>    LOG.info("Finished waiting on RegionServer count=" + count + "; waited=" + slept + "ms,"<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      + " expected min=" + minToStart + " server(s), max=" + getStrForMax(maxToStart)<a name="line.810"></a>
-<span class="sourceLineNo">811</span>      + " server(s)," + " master is " + (this.master.isStopped() ? "stopped." : "running"));<a name="line.811"></a>
-<span class="sourceLineNo">812</span>  }<a name="line.812"></a>
-<span class="sourceLineNo">813</span><a name="line.813"></a>
-<span class="sourceLineNo">814</span>  private String getStrForMax(final int max) {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    return max == Integer.MAX_VALUE ? "NO_LIMIT" : Integer.toString(max);<a name="line.815"></a>
-<span class="sourceLineNo">816</span>  }<a name="line.816"></a>
-<span class="sourceLineNo">817</span><a name="line.817"></a>
-<span class="sourceLineNo">818</span>  /** Returns A copy of the internal list of online servers. */<a name="line.818"></a>
-<span class="sourceLineNo">819</span>  public List&lt;ServerName&gt; getOnlineServersList() {<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    // TODO: optimize the load balancer call so we don't need to make a new list<a name="line.820"></a>
-<span class="sourceLineNo">821</span>    // TODO: FIX. THIS IS POPULAR CALL.<a name="line.821"></a>
-<span class="sourceLineNo">822</span>    return new ArrayList&lt;&gt;(this.onlineServers.keySet());<a name="line.822"></a>
-<span class="sourceLineNo">823</span>  }<a name="line.823"></a>
-<span class="sourceLineNo">824</span><a name="line.824"></a>
-<span class="sourceLineNo">825</span>  /**<a name="line.825"></a>
-<span class="sourceLineNo">826</span>   * @param keys                 The target server name<a name="line.826"></a>
-<span class="sourceLineNo">827</span>   * @param idleServerPredicator Evaluates the server on the given load<a name="line.827"></a>
-<span class="sourceLineNo">828</span>   * @return A copy of the internal list of online servers matched by the predicator<a name="line.828"></a>
-<span class="sourceLineNo">829</span>   */<a name="line.829"></a>
-<span class="sourceLineNo">830</span>  public List&lt;ServerName&gt; getOnlineServersListWithPredicator(List&lt;ServerName&gt; keys,<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    Predicate&lt;ServerMetrics&gt; idleServerPredicator) {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>    List&lt;ServerName&gt; names = new ArrayList&lt;&gt;();<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    if (keys != null &amp;&amp; idleServerPredicator != null) {<a name="line.833"></a>
-<span class="sourceLineNo">834</span>      keys.forEach(name -&gt; {<a name="line.834"></a>
-<span class="sourceLineNo">835</span>        ServerMetrics load = onlineServers.get(name);<a name="line.835"></a>
-<span class="sourceLineNo">836</span>        if (load != null) {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>          if (idleServerPredicator.test(load)) {<a name="line.837"></a>
-<span class="sourceLineNo">838</span>            names.add(name);<a name="line.838"></a>
-<span class="sourceLineNo">839</span>          }<a name="line.839"></a>
-<span class="sourceLineNo">840</span>        }<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      });<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    return names;<a name="line.843"></a>
-<span class="sourceLineNo">844</span>  }<a name="line.844"></a>
-<span class="sourceLineNo">845</span><a name="line.845"></a>
-<span class="sourceLineNo">846</span>  /** Returns A copy of the internal list of draining servers. */<a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public List&lt;ServerName&gt; getDrainingServersList() {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    return new ArrayList&lt;&gt;(this.drainingServers);<a name="line.848"></a>
+<span class="sourceLineNo">222</span>    // if use-ip is enabled, we will use ip to expose Master/RS service for client,<a name="line.222"></a>
+<span class="sourceLineNo">223</span>    // see HBASE-27304 for details.<a name="line.223"></a>
+<span class="sourceLineNo">224</span>    boolean useIp = master.getConfiguration().getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY,<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>    String isaHostName = useIp ? ia.getHostAddress() : ia.getHostName();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    final String hostname =<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      request.hasUseThisHostnameInstead() ? request.getUseThisHostnameInstead() : isaHostName;<a name="line.228"></a>
+<span class="sourceLineNo">229</span>    ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    checkClockSkew(sn, request.getServerCurrentTime());<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    checkIsDead(sn, "STARTUP");<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    if (!checkAndRecordNewServer(sn, ServerMetricsBuilder.of(sn, versionNumber, version))) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      LOG.warn(<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        "THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);<a name="line.234"></a>
+<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    storage.started(sn);<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    return sn;<a name="line.237"></a>
+<span class="sourceLineNo">238</span>  }<a name="line.238"></a>
+<span class="sourceLineNo">239</span><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Updates last flushed sequence Ids for the regions on server sn<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   */<a name="line.242"></a>
+<span class="sourceLineNo">243</span>  private void updateLastFlushedSequenceIds(ServerName sn, ServerMetrics hsl) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    for (Entry&lt;byte[], RegionMetrics&gt; entry : hsl.getRegionMetrics().entrySet()) {<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey()));<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.246"></a>
+<span class="sourceLineNo">247</span>      long l = entry.getValue().getCompletedSequenceId();<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      // Don't let smaller sequence ids override greater sequence ids.<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      if (LOG.isTraceEnabled()) {<a name="line.249"></a>
+<span class="sourceLineNo">250</span>        LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue<a name="line.250"></a>
+<span class="sourceLineNo">251</span>          + ", completeSequenceId=" + l);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>      }<a name="line.252"></a>
+<span class="sourceLineNo">253</span>      if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue)) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>        flushedSequenceIdByRegion.put(encodedRegionName, l);<a name="line.254"></a>
+<span class="sourceLineNo">255</span>      } else if (l != HConstants.NO_SEQNUM &amp;&amp; l &lt; existingValue) {<a name="line.255"></a>
+<span class="sourceLineNo">256</span>        LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l<a name="line.256"></a>
+<span class="sourceLineNo">257</span>          + ") that is less than the previous last flushed sequence id (" + existingValue<a name="line.257"></a>
+<span class="sourceLineNo">258</span>          + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring.");<a name="line.258"></a>
+<span class="sourceLineNo">259</span>      }<a name="line.259"></a>
+<span class="sourceLineNo">260</span>      ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>        computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.261"></a>
+<span class="sourceLineNo">262</span>          () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      for (Entry&lt;byte[], Long&gt; storeSeqId : entry.getValue().getStoreSequenceId().entrySet()) {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>        byte[] family = storeSeqId.getKey();<a name="line.264"></a>
+<span class="sourceLineNo">265</span>        existingValue = storeFlushedSequenceId.get(family);<a name="line.265"></a>
+<span class="sourceLineNo">266</span>        l = storeSeqId.getValue();<a name="line.266"></a>
+<span class="sourceLineNo">267</span>        if (LOG.isTraceEnabled()) {<a name="line.267"></a>
+<span class="sourceLineNo">268</span>          LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family)<a name="line.268"></a>
+<span class="sourceLineNo">269</span>            + ", existingValue=" + existingValue + ", completeSequenceId=" + l);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>        }<a name="line.270"></a>
+<span class="sourceLineNo">271</span>        // Don't let smaller sequence ids override greater sequence ids.<a name="line.271"></a>
+<span class="sourceLineNo">272</span>        if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue.longValue())) {<a name="line.272"></a>
+<span class="sourceLineNo">273</span>          storeFlushedSequenceId.put(family, l);<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        }<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      }<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    }<a name="line.276"></a>
+<span class="sourceLineNo">277</span>  }<a name="line.277"></a>
+<span class="sourceLineNo">278</span><a name="line.278"></a>
+<span class="sourceLineNo">279</span>  public void regionServerReport(ServerName sn, ServerMetrics sl) throws YouAreDeadException {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>    checkIsDead(sn, "REPORT");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>    if (null == this.onlineServers.replace(sn, sl)) {<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      // Already have this host+port combo and its just different start code?<a name="line.282"></a>
+<span class="sourceLineNo">283</span>      // Just let the server in. Presume master joining a running cluster.<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      // recordNewServer is what happens at the end of reportServerStartup.<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      // The only thing we are skipping is passing back to the regionserver<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      // the ServerName to use. Here we presume a master has already done<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      // that so we'll press on with whatever it gave us for ServerName.<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      if (!checkAndRecordNewServer(sn, sl)) {<a name="line.288"></a>
+<span class="sourceLineNo">289</span>        LOG.info("RegionServerReport ignored, could not record the server: " + sn);<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        return; // Not recorded, so no need to move on<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      }<a name="line.291"></a>
+<span class="sourceLineNo">292</span>    }<a name="line.292"></a>
+<span class="sourceLineNo">293</span>    updateLastFlushedSequenceIds(sn, sl);<a name="line.293"></a>
+<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
+<span class="sourceLineNo">295</span><a name="line.295"></a>
+<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
+<span class="sourceLineNo">297</span>   * Check is a server of same host and port already exists, if not, or the existed one got a<a name="line.297"></a>
+<span class="sourceLineNo">298</span>   * smaller start code, record it.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>   * @param serverName the server to check and record<a name="line.299"></a>
+<span class="sourceLineNo">300</span>   * @param sl         the server load on the server<a name="line.300"></a>
+<span class="sourceLineNo">301</span>   * @return true if the server is recorded, otherwise, false<a name="line.301"></a>
+<span class="sourceLineNo">302</span>   */<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  boolean checkAndRecordNewServer(final ServerName serverName, final ServerMetrics sl) {<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    ServerName existingServer = null;<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    synchronized (this.onlineServers) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      existingServer = findServerWithSameHostnamePortWithLock(serverName);<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      if (existingServer != null &amp;&amp; (existingServer.getStartcode() &gt; serverName.getStartcode())) {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>        LOG.info("Server serverName=" + serverName + " rejected; we already have "<a name="line.308"></a>
+<span class="sourceLineNo">309</span>          + existingServer.toString() + " registered with same hostname and port");<a name="line.309"></a>
+<span class="sourceLineNo">310</span>        return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>      }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>      recordNewServerWithLock(serverName, sl);<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>    // Tell our listeners that a server was added<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    if (!this.listeners.isEmpty()) {<a name="line.316"></a>
+<span class="sourceLineNo">317</span>      for (ServerListener listener : this.listeners) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>        listener.serverAdded(serverName);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>      }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>    // Note that we assume that same ts means same server, and don't expire in that case.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    // TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    if (existingServer != null &amp;&amp; (existingServer.getStartcode() &lt; serverName.getStartcode())) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      LOG.info("Triggering server recovery; existingServer " + existingServer<a name="line.325"></a>
+<span class="sourceLineNo">326</span>        + " looks stale, new server:" + serverName);<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      expireServer(existingServer);<a name="line.327"></a>
+<span class="sourceLineNo">328</span>    }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    return true;<a name="line.329"></a>
+<span class="sourceLineNo">330</span>  }<a name="line.330"></a>
+<span class="sourceLineNo">331</span><a name="line.331"></a>
+<span class="sourceLineNo">332</span>  /**<a name="line.332"></a>
+<span class="sourceLineNo">333</span>   * Find out the region servers crashed between the crash of the previous master instance and the<a name="line.333"></a>
+<span class="sourceLineNo">334</span>   * current master instance and schedule SCP for them.<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * &lt;p/&gt;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * Since the {@code RegionServerTracker} has already helped us to construct the online servers set<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * by scanning zookeeper, now we can compare the online servers with {@code liveServersFromWALDir}<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   * to find out whether there are servers which are already dead.<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * &lt;p/&gt;<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * Must be called inside the initialization method of {@code RegionServerTracker} to avoid<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   * concurrency issue.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>   * @param deadServersFromPE     the region servers which already have a SCP associated.<a name="line.342"></a>
+<span class="sourceLineNo">343</span>   * @param liveServersFromWALDir the live region servers from wal directory.<a name="line.343"></a>
+<span class="sourceLineNo">344</span>   */<a name="line.344"></a>
+<span class="sourceLineNo">345</span>  void findDeadServersAndProcess(Set&lt;ServerName&gt; deadServersFromPE,<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    Set&lt;ServerName&gt; liveServersFromWALDir) {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    deadServersFromPE.forEach(deadservers::putIfAbsent);<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    liveServersFromWALDir.stream().filter(sn -&gt; !onlineServers.containsKey(sn))<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      .forEach(this::expireServer);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>  }<a name="line.350"></a>
+<span class="sourceLineNo">351</span><a name="line.351"></a>
+<span class="sourceLineNo">352</span>  /**<a name="line.352"></a>
+<span class="sourceLineNo">353</span>   * Checks if the clock skew between the server and the master. If the clock skew exceeds the<a name="line.353"></a>
+<span class="sourceLineNo">354</span>   * configured max, it will throw an exception; if it exceeds the configured warning threshold, it<a name="line.354"></a>
+<span class="sourceLineNo">355</span>   * will log a warning but start normally.<a name="line.355"></a>
+<span class="sourceLineNo">356</span>   * @param serverName Incoming servers's name n * @throws ClockOutOfSyncException if the skew<a name="line.356"></a>
+<span class="sourceLineNo">357</span>   *                   exceeds the configured max value<a name="line.357"></a>
+<span class="sourceLineNo">358</span>   */<a name="line.358"></a>
+<span class="sourceLineNo">359</span>  private void checkClockSkew(final ServerName serverName, final long serverCurrentTime)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    throws ClockOutOfSyncException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    long skew = Math.abs(EnvironmentEdgeManager.currentTime() - serverCurrentTime);<a name="line.361"></a>
+<span class="sourceLineNo">362</span>    if (skew &gt; maxSkew) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      String message = "Server " + serverName + " has been "<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        + "rejected; Reported time is too far out of sync with master.  " + "Time difference of "<a name="line.364"></a>
+<span class="sourceLineNo">365</span>        + skew + "ms &gt; max allowed of " + maxSkew + "ms";<a name="line.365"></a>
+<span class="sourceLineNo">366</span>      LOG.warn(message);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>      throw new ClockOutOfSyncException(message);<a name="line.367"></a>
+<span class="sourceLineNo">368</span>    } else if (skew &gt; warningSkew) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      String message = "Reported time for server " + serverName + " is out of sync with master "<a name="line.369"></a>
+<span class="sourceLineNo">370</span>        + "by " + skew + "ms. (Warning threshold is " + warningSkew + "ms; " + "error threshold is "<a name="line.370"></a>
+<span class="sourceLineNo">371</span>        + maxSkew + "ms)";<a name="line.371"></a>
+<span class="sourceLineNo">372</span>      LOG.warn(message);<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
+<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
+<span class="sourceLineNo">375</span><a name="line.375"></a>
+<span class="sourceLineNo">376</span>  /**<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * Called when RegionServer first reports in for duty and thereafter each time it heartbeats to<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   * make sure it is has not been figured for dead. If this server is on the dead list, reject it<a name="line.378"></a>
+<span class="sourceLineNo">379</span>   * with a YouAreDeadException. If it was dead but came back with a new start code, remove the old<a name="line.379"></a>
+<span class="sourceLineNo">380</span>   * entry from the dead list.<a name="line.380"></a>
+<span class="sourceLineNo">381</span>   * @param what START or REPORT<a name="line.381"></a>
+<span class="sourceLineNo">382</span>   */<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  private void checkIsDead(final ServerName serverName, final String what)<a name="line.383"></a>
+<span class="sourceLineNo">384</span>    throws YouAreDeadException {<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      // Exact match: host name, port and start code all match with existing one of the<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      // dead servers. So, this server must be dead. Tell it to kill itself.<a name="line.387"></a>
+<span class="sourceLineNo">388</span>      String message =<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        "Server " + what + " rejected; currently processing " + serverName + " as dead server";<a name="line.389"></a>
+<span class="sourceLineNo">390</span>      LOG.debug(message);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>      throw new YouAreDeadException(message);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    }<a name="line.392"></a>
+<span class="sourceLineNo">393</span>    // Remove dead server with same hostname and port of newly checking in rs after master<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    // initialization. See HBASE-5916 for more information.<a name="line.394"></a>
+<span class="sourceLineNo">395</span>    if (<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      (this.master == null || this.master.isInitialized())<a name="line.396"></a>
+<span class="sourceLineNo">397</span>        &amp;&amp; this.deadservers.cleanPreviousInstance(serverName)<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    ) {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>      // This server has now become alive after we marked it as dead.<a name="line.399"></a>
+<span class="sourceLineNo">400</span>      // We removed it's previous entry from the dead list to reflect it.<a name="line.400"></a>
+<span class="sourceLineNo">401</span>      LOG.debug("{} {} came back up, removed it from the dead servers list", what, serverName);<a name="line.401"></a>
+<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
+<span class="sourceLineNo">403</span>  }<a name="line.403"></a>
+<span class="sourceLineNo">404</span><a name="line.404"></a>
+<span class="sourceLineNo">405</span>  /**<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * Assumes onlineServers is locked.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   * @return ServerName with matching hostname and port.<a name="line.407"></a>
+<span class="sourceLineNo">408</span>   */<a name="line.408"></a>
+<span class="sourceLineNo">409</span>  private ServerName findServerWithSameHostnamePortWithLock(final ServerName serverName) {<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    ServerName end =<a name="line.410"></a>
+<span class="sourceLineNo">411</span>      ServerName.valueOf(serverName.getHostname(), serverName.getPort(), Long.MAX_VALUE);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>    ServerName r = onlineServers.lowerKey(end);<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    if (r != null) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      if (ServerName.isSameAddress(r, serverName)) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>        return r;<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      }<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    return null;<a name="line.419"></a>
+<span class="sourceLineNo">420</span>  }<a name="line.420"></a>
+<span class="sourceLineNo">421</span><a name="line.421"></a>
+<span class="sourceLineNo">422</span>  /**<a name="line.422"></a>
+<span class="sourceLineNo">423</span>   * Adds the onlineServers list. onlineServers should be locked.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>   * @param serverName The remote servers name.<a name="line.424"></a>
+<span class="sourceLineNo">425</span>   */<a name="line.425"></a>
+<span class="sourceLineNo">426</span>  void recordNewServerWithLock(final ServerName serverName, final ServerMetrics sl) {<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    LOG.info("Registering regionserver=" + serverName);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>    this.onlineServers.put(serverName, sl);<a name="line.428"></a>
+<span class="sourceLineNo">429</span>  }<a name="line.429"></a>
+<span class="sourceLineNo">430</span><a name="line.430"></a>
+<span class="sourceLineNo">431</span>  public ConcurrentNavigableMap&lt;byte[], Long&gt; getFlushedSequenceIdByRegion() {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    return flushedSequenceIdByRegion;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>  }<a name="line.433"></a>
+<span class="sourceLineNo">434</span><a name="line.434"></a>
+<span class="sourceLineNo">435</span>  public RegionStoreSequenceIds getLastFlushedSequenceId(byte[] encodedRegionName) {<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    RegionStoreSequenceIds.Builder builder = RegionStoreSequenceIds.newBuilder();<a name="line.436"></a>
+<span class="sourceLineNo">437</span>    Long seqId = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.437"></a>
+<span class="sourceLineNo">438</span>    builder.setLastFlushedSequenceId(seqId != null ? seqId.longValue() : HConstants.NO_SEQNUM);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>    Map&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      storeFlushedSequenceIdsByRegion.get(encodedRegionName);<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    if (storeFlushedSequenceId != null) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      for (Map.Entry&lt;byte[], Long&gt; entry : storeFlushedSequenceId.entrySet()) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        builder.addStoreSequenceId(StoreSequenceId.newBuilder()<a name="line.443"></a>
+<span class="sourceLineNo">444</span>          .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey()))<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          .setSequenceId(entry.getValue().longValue()).build());<a name="line.445"></a>
+<span class="sourceLineNo">446</span>      }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>    }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>    return builder.build();<a name="line.448"></a>
+<span class="sourceLineNo">449</span>  }<a name="line.449"></a>
+<span class="sourceLineNo">450</span><a name="line.450"></a>
+<span class="sourceLineNo">451</span>  /**<a name="line.451"></a>
+<span class="sourceLineNo">452</span>   * n * @return ServerMetrics if serverName is known else null<a name="line.452"></a>
+<span class="sourceLineNo">453</span>   */<a name="line.453"></a>
+<span class="sourceLineNo">454</span>  public ServerMetrics getLoad(final ServerName serverName) {<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    return this.onlineServers.get(serverName);<a name="line.455"></a>
+<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
+<span class="sourceLineNo">457</span><a name="line.457"></a>
+<span class="sourceLineNo">458</span>  /**<a name="line.458"></a>
+<span class="sourceLineNo">459</span>   * Compute the average load across all region servers. Currently, this uses a very naive<a name="line.459"></a>
+<span class="sourceLineNo">460</span>   * computation - just uses the number of regions being served, ignoring stats about number of<a name="line.460"></a>
+<span class="sourceLineNo">461</span>   * requests.<a name="line.461"></a>
+<span class="sourceLineNo">462</span>   * @return the average load<a name="line.462"></a>
+<span class="sourceLineNo">463</span>   */<a name="line.463"></a>
+<span class="sourceLineNo">464</span>  public double getAverageLoad() {<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    int totalLoad = 0;<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    int numServers = 0;<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    for (ServerMetrics sl : this.onlineServers.values()) {<a name="line.467"></a>
+<span class="sourceLineNo">468</span>      numServers++;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>      totalLoad += sl.getRegionMetrics().size();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    }<a name="line.470"></a>
+<span class="sourceLineNo">471</span>    return numServers == 0 ? 0 : (double) totalLoad / (double) numServers;<a name="line.471"></a>
+<span class="sourceLineNo">472</span>  }<a name="line.472"></a>
+<span class="sourceLineNo">473</span><a name="line.473"></a>
+<span class="sourceLineNo">474</span>  /** Returns the count of active regionservers */<a name="line.474"></a>
+<span class="sourceLineNo">475</span>  public int countOfRegionServers() {<a name="line.475"></a>
+<span class="sourceLineNo">476</span>    // Presumes onlineServers is a concurrent map<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    return this.onlineServers.size();<a name="line.477"></a>
+<span class="sourceLineNo">478</span>  }<a name="line.478"></a>
+<span class="sourceLineNo">479</span><a name="line.479"></a>
+<span class="sourceLineNo">480</span>  /** Returns Read-only map of servers to serverinfo */<a name="line.480"></a>
+<span class="sourceLineNo">481</span>  public Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    // Presumption is that iterating the returned Map is OK.<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    synchronized (this.onlineServers) {<a name="line.483"></a>
+<span class="sourceLineNo">484</span>      return Collections.unmodifiableMap(this.onlineServers);<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    }<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  public DeadServer getDeadServers() {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    return this.deadservers;<a name="line.489"></a>
+<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
+<span class="sourceLineNo">491</span><a name="line.491"></a>
+<span class="sourceLineNo">492</span>  /**<a name="line.492"></a>
+<span class="sourceLineNo">493</span>   * Checks if any dead servers are currently in progress.<a name="line.493"></a>
+<span class="sourceLineNo">494</span>   * @return true if any RS are being processed as dead, false if not<a name="line.494"></a>
+<span class="sourceLineNo">495</span>   */<a name="line.495"></a>
+<span class="sourceLineNo">496</span>  public boolean areDeadServersInProgress() throws IOException {<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    return master.getProcedures().stream()<a name="line.497"></a>
+<span class="sourceLineNo">498</span>      .anyMatch(p -&gt; !p.isFinished() &amp;&amp; p instanceof ServerCrashProcedure);<a name="line.498"></a>
+<span class="sourceLineNo">499</span>  }<a name="line.499"></a>
+<span class="sourceLineNo">500</span><a name="line.500"></a>
+<span class="sourceLineNo">501</span>  void letRegionServersShutdown() {<a name="line.501"></a>
+<span class="sourceLineNo">502</span>    long previousLogTime = 0;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>    ServerName sn = master.getServerName();<a name="line.503"></a>
+<span class="sourceLineNo">504</span>    ZKWatcher zkw = master.getZooKeeper();<a name="line.504"></a>
+<span class="sourceLineNo">505</span>    int onlineServersCt;<a name="line.505"></a>
+<span class="sourceLineNo">506</span>    while ((onlineServersCt = onlineServers.size()) &gt; 0) {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {<a name="line.507"></a>
+<span class="sourceLineNo">508</span>        Set&lt;ServerName&gt; remainingServers = onlineServers.keySet();<a name="line.508"></a>
+<span class="sourceLineNo">509</span>        synchronized (onlineServers) {<a name="line.509"></a>
+<span class="sourceLineNo">510</span>          if (remainingServers.size() == 1 &amp;&amp; remainingServers.contains(sn)) {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>            // Master will delete itself later.<a name="line.511"></a>
+<span class="sourceLineNo">512</span>            return;<a name="line.512"></a>
+<span class="sourceLineNo">513</span>          }<a name="line.513"></a>
+<span class="sourceLineNo">514</span>        }<a name="line.514"></a>
+<span class="sourceLineNo">515</span>        StringBuilder sb = new StringBuilder();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>        // It's ok here to not sync on onlineServers - merely logging<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        for (ServerName key : remainingServers) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>          if (sb.length() &gt; 0) {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>            sb.append(", ");<a name="line.519"></a>
+<span class="sourceLineNo">520</span>          }<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          sb.append(key);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        }<a name="line.522"></a>
+<span class="sourceLineNo">523</span>        LOG.info("Waiting on regionserver(s) " + sb.toString());<a name="line.523"></a>
+<span class="sourceLineNo">524</span>        previousLogTime = EnvironmentEdgeManager.currentTime();<a name="line.524"></a>
+<span class="sourceLineNo">525</span>      }<a name="line.525"></a>
+<span class="sourceLineNo">526</span><a name="line.526"></a>
+<span class="sourceLineNo">527</span>      try {<a name="line.527"></a>
+<span class="sourceLineNo">528</span>        List&lt;String&gt; servers = getRegionServersInZK(zkw);<a name="line.528"></a>
+<span class="sourceLineNo">529</span>        if (<a name="line.529"></a>
+<span class="sourceLineNo">530</span>          servers == null || servers.isEmpty()<a name="line.530"></a>
+<span class="sourceLineNo">531</span>            || (servers.size() == 1 &amp;&amp; servers.contains(sn.toString()))<a name="line.531"></a>
+<span class="sourceLineNo">532</span>        ) {<a name="line.532"></a>
+<span class="sourceLineNo">533</span>          LOG.info("ZK shows there is only the master self online, exiting now");<a name="line.533"></a>
+<span class="sourceLineNo">534</span>          // Master could have lost some ZK events, no need to wait more.<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          break;<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        }<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      } catch (KeeperException ke) {<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        LOG.warn("Failed to list regionservers", ke);<a name="line.538"></a>
+<span class="sourceLineNo">539</span>        // ZK is malfunctioning, don't hang here<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        break;<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>      synchronized (onlineServers) {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>        try {<a name="line.543"></a>
+<span class="sourceLineNo">544</span>          if (onlineServersCt == onlineServers.size()) onlineServers.wait(100);<a name="line.544"></a>
+<span class="sourceLineNo">545</span>        } catch (InterruptedException ignored) {<a name="line.545"></a>
+<span class="sourceLineNo">546</span>          // continue<a name="line.546"></a>
+<span class="sourceLineNo">547</span>        }<a name="line.547"></a>
+<span class="sourceLineNo">548</span>      }<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
+<span class="sourceLineNo">550</span>  }<a name="line.550"></a>
+<span class="sourceLineNo">551</span><a name="line.551"></a>
+<span class="sourceLineNo">552</span>  private List&lt;String&gt; getRegionServersInZK(final ZKWatcher zkw) throws KeeperException {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>    return ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode);<a name="line.553"></a>
+<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
+<span class="sourceLineNo">555</span><a name="line.555"></a>
+<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
+<span class="sourceLineNo">557</span>   * Expire the passed server. Add it to list of dead servers and queue a shutdown processing.<a name="line.557"></a>
+<span class="sourceLineNo">558</span>   * @return pid if we queued a ServerCrashProcedure else {@link Procedure#NO_PROC_ID} if we did not<a name="line.558"></a>
+<span class="sourceLineNo">559</span>   *         (could happen for many reasons including the fact that its this server that is going<a name="line.559"></a>
+<span class="sourceLineNo">560</span>   *         down or we already have queued an SCP for this server or SCP processing is currently<a name="line.560"></a>
+<span class="sourceLineNo">561</span>   *         disabled because we are in startup phase).<a name="line.561"></a>
+<span class="sourceLineNo">562</span>   */<a name="line.562"></a>
+<span class="sourceLineNo">563</span>  // Redo test so we can make this protected.<a name="line.563"></a>
+<span class="sourceLineNo">564</span>  public synchronized long expireServer(final ServerName serverName) {<a name="line.564"></a>
+<span class="sourceLineNo">565</span>    return expireServer(serverName, false);<a name="line.565"></a>
+<span class="sourceLineNo">566</span><a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  synchronized long expireServer(final ServerName serverName, boolean force) {<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    // THIS server is going down... can't handle our own expiration.<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    if (serverName.equals(master.getServerName())) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      if (!(master.isAborted() || master.isStopped())) {<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        master.stop("We lost our znode?");<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>      return Procedure.NO_PROC_ID;<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    }<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.warn("Expiration called on {} but already in DeadServer", serverName);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return Procedure.NO_PROC_ID;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span>    moveFromOnlineToDeadServers(serverName);<a name="line.581"></a>
+<span class="sourceLineNo">582</span><a name="line.582"></a>
+<span class="sourceLineNo">583</span>    // If server is in draining mode, remove corresponding znode<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    // In some tests, the mocked HM may not have ZK Instance, hence null check<a name="line.584"></a>
+<span class="sourceLineNo">585</span>    if (master.getZooKeeper() != null) {<a name="line.585"></a>
+<span class="sourceLineNo">586</span>      String drainingZnode = ZNodePaths<a name="line.586"></a>
+<span class="sourceLineNo">587</span>        .joinZNode(master.getZooKeeper().getZNodePaths().drainingZNode, serverName.getServerName());<a name="line.587"></a>
+<span class="sourceLineNo">588</span>      try {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        ZKUtil.deleteNodeFailSilent(master.getZooKeeper(), drainingZnode);<a name="line.589"></a>
+<span class="sourceLineNo">590</span>      } catch (KeeperException e) {<a name="line.590"></a>
+<span class="sourceLineNo">591</span>        LOG.warn(<a name="line.591"></a>
+<span class="sourceLineNo">592</span>          "Error deleting the draining znode for stopping server " + serverName.getServerName(), e);<a name="line.592"></a>
+<span class="sourceLineNo">593</span>      }<a name="line.593"></a>
+<span class="sourceLineNo">594</span>    }<a name="line.594"></a>
+<span class="sourceLineNo">595</span><a name="line.595"></a>
+<span class="sourceLineNo">596</span>    // If cluster is going down, yes, servers are going to be expiring; don't<a name="line.596"></a>
+<span class="sourceLineNo">597</span>    // process as a dead server<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    if (isClusterShutdown()) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>      LOG.info("Cluster shutdown set; " + serverName + " expired; onlineServers="<a name="line.599"></a>
+<span class="sourceLineNo">600</span>        + this.onlineServers.size());<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      if (this.onlineServers.isEmpty()) {<a name="line.601"></a>
+<span class="sourceLineNo">602</span>        master.stop("Cluster shutdown set; onlineServer=0");<a name="line.602"></a>
+<span class="sourceLineNo">603</span>      }<a name="line.603"></a>
+<span class="sourceLineNo">604</span>      return Procedure.NO_PROC_ID;<a name="line.604"></a>
+<span class="sourceLineNo">605</span>    }<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    LOG.info("Processing expiration of " + serverName + " on " + this.master.getServerName());<a name="line.606"></a>
+<span class="sourceLineNo">607</span>    long pid = master.getAssignmentManager().submitServerCrash(serverName, true, force);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>    storage.expired(serverName);<a name="line.608"></a>
+<span class="sourceLineNo">609</span>    // Tell our listeners that a server was removed<a name="line.609"></a>
+<span class="sourceLineNo">610</span>    if (!this.listeners.isEmpty()) {<a name="line.610"></a>
+<span class="sourceLineNo">611</span>      this.listeners.stream().forEach(l -&gt; l.serverRemoved(serverName));<a name="line.611"></a>
+<span class="sourceLineNo">612</span>    }<a name="line.612"></a>
+<span class="sourceLineNo">613</span>    // trigger a persist of flushedSeqId<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    if (flushedSeqIdFlusher != null) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>      flushedSeqIdFlusher.triggerNow();<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    }<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    return pid;<a name="line.617"></a>
+<span class="sourceLineNo">618</span>  }<a name="line.618"></a>
+<span class="sourceLineNo">619</span><a name="line.619"></a>
+<span class="sourceLineNo">620</span>  /**<a name="line.620"></a>
+<span class="sourceLineNo">621</span>   * Called when server has expired.<a name="line.621"></a>
+<span class="sourceLineNo">622</span>   */<a name="line.622"></a>
+<span class="sourceLineNo">623</span>  // Locking in this class needs cleanup.<a name="line.623"></a>
+<span class="sourceLineNo">624</span>  public synchronized void moveFromOnlineToDeadServers(final ServerName sn) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>    synchronized (this.onlineServers) {<a name="line.625"></a>
+<span class="sourceLineNo">626</span>      boolean online = this.onlineServers.containsKey(sn);<a name="line.626"></a>
+<span class="sourceLineNo">627</span>      if (online) {<a name="line.627"></a>
+<span class="sourceLineNo">628</span>        // Remove the server from the known servers lists and update load info BUT<a name="line.628"></a>
+<span class="sourceLineNo">629</span>        // add to deadservers first; do this so it'll show in dead servers list if<a name="line.629"></a>
+<span class="sourceLineNo">630</span>        // not in online servers list.<a name="line.630"></a>
+<span class="sourceLineNo">631</span>        this.deadservers.putIfAbsent(sn);<a name="line.631"></a>
+<span class="sourceLineNo">632</span>        this.onlineServers.remove(sn);<a name="line.632"></a>
+<span class="sourceLineNo">633</span>        onlineServers.notifyAll();<a name="line.633"></a>
+<span class="sourceLineNo">634</span>      } else {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>        // If not online, that is odd but may happen if 'Unknown Servers' -- where meta<a name="line.635"></a>
+<span class="sourceLineNo">636</span>        // has references to servers not online nor in dead servers list. If<a name="line.636"></a>
+<span class="sourceLineNo">637</span>        // 'Unknown Server', don't add to DeadServers else will be there for ever.<a name="line.637"></a>
+<span class="sourceLineNo">638</span>        LOG.trace("Expiration of {} but server not online", sn);<a name="line.638"></a>
+<span class="sourceLineNo">639</span>      }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>    }<a name="line.640"></a>
+<span class="sourceLineNo">641</span>  }<a name="line.641"></a>
+<span class="sourceLineNo">642</span><a name="line.642"></a>
+<span class="sourceLineNo">643</span>  /*<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   * Remove the server from the drain list.<a name="line.644"></a>
+<span class="sourceLineNo">645</span>   */<a name="line.645"></a>
+<span class="sourceLineNo">646</span>  public synchronized boolean removeServerFromDrainList(final ServerName sn) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.648"></a>
+<span class="sourceLineNo">649</span><a name="line.649"></a>
+<span class="sourceLineNo">650</span>    if (!this.isServerOnline(sn)) {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        + "Removing from draining list anyway, as requested.");<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    // Remove the server from the draining servers lists.<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    return this.drainingServers.remove(sn);<a name="line.655"></a>
+<span class="sourceLineNo">656</span>  }<a name="line.656"></a>
+<span class="sourceLineNo">657</span><a name="line.657"></a>
+<span class="sourceLineNo">658</span>  /**<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   * Add the server to the drain list. n * @return True if the server is added or the server is<a name="line.659"></a>
+<span class="sourceLineNo">660</span>   * already on the drain list.<a name="line.660"></a>
+<span class="sourceLineNo">661</span>   */<a name="line.661"></a>
+<span class="sourceLineNo">662</span>  public synchronized boolean addServerToDrainList(final ServerName sn) {<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.663"></a>
+<span class="sourceLineNo">664</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.664"></a>
+<span class="sourceLineNo">665</span><a name="line.665"></a>
+<span class="sourceLineNo">666</span>    if (!this.isServerOnline(sn)) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        + "Ignoring request to add it to draining list.");<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      return false;<a name="line.669"></a>
+<span class="sourceLineNo">670</span>    }<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    // Add the server to the draining servers lists, if it's not already in<a name="line.671"></a>
+<span class="sourceLineNo">672</span>    // it.<a name="line.672"></a>
+<span class="sourceLineNo">673</span>    if (this.drainingServers.contains(sn)) {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>      LOG.warn("Server " + sn + " is already in the draining server list."<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        + "Ignoring request to add it again.");<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      return true;<a name="line.676"></a>
+<span class="sourceLineNo">677</span>    }<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    LOG.info("Server " + sn + " added to draining server list.");<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    return this.drainingServers.add(sn);<a name="line.679"></a>
+<span class="sourceLineNo">680</span>  }<a name="line.680"></a>
+<span class="sourceLineNo">681</span><a name="line.681"></a>
+<span class="sourceLineNo">682</span>  /**<a name="line.682"></a>
+<span class="sourceLineNo">683</span>   * Contacts a region server and waits up to timeout ms to close the region. This bypasses the<a name="line.683"></a>
+<span class="sourceLineNo">684</span>   * active hmaster. Pass -1 as timeout if you do not want to wait on result.<a name="line.684"></a>
+<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
+<span class="sourceLineNo">686</span>  public static void closeRegionSilentlyAndWait(AsyncClusterConnection connection,<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    ServerName server, RegionInfo region, long timeout) throws IOException, InterruptedException {<a name="line.687"></a>
+<span class="sourceLineNo">688</span>    AsyncRegionServerAdmin admin = connection.getRegionServerAdmin(server);<a name="line.688"></a>
+<span class="sourceLineNo">689</span>    try {<a name="line.689"></a>
+<span class="sourceLineNo">690</span>      FutureUtils.get(<a name="line.690"></a>
+<span class="sourceLineNo">691</span>        admin.closeRegion(ProtobufUtil.buildCloseRegionRequest(server, region.getRegionName())));<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    } catch (IOException e) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>      LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);<a name="line.693"></a>
+<span class="sourceLineNo">694</span>    }<a name="line.694"></a>
+<span class="sourceLineNo">695</span>    if (timeout &lt; 0) {<a name="line.695"></a>
+<span class="sourceLineNo">696</span>      return;<a name="line.696"></a>
+<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
+<span class="sourceLineNo">698</span>    long expiration = timeout + EnvironmentEdgeManager.currentTime();<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    while (EnvironmentEdgeManager.currentTime() &lt; expiration) {<a name="line.699"></a>
+<span class="sourceLineNo">700</span>      try {<a name="line.700"></a>
+<span class="sourceLineNo">701</span>        RegionInfo rsRegion = ProtobufUtil.toRegionInfo(FutureUtils<a name="line.701"></a>
+<span class="sourceLineNo">702</span>          .get(<a name="line.702"></a>
+<span class="sourceLineNo">703</span>            admin.getRegionInfo(RequestConverter.buildGetRegionInfoRequest(region.getRegionName())))<a name="line.703"></a>
+<span class="sourceLineNo">704</span>          .getRegionInfo());<a name="line.704"></a>
+<span class="sourceLineNo">705</span>        if (rsRegion == null) {<a name="line.705"></a>
+<span class="sourceLineNo">706</span>          return;<a name="line.706"></a>
+<span class="sourceLineNo">707</span>        }<a name="line.707"></a>
+<span class="sourceLineNo">708</span>      } catch (IOException ioe) {<a name="line.708"></a>
+<span class="sourceLineNo">709</span>        if (<a name="line.709"></a>
+<span class="sourceLineNo">710</span>          ioe instanceof NotServingRegionException<a name="line.710"></a>
+<span class="sourceLineNo">711</span>            || (ioe instanceof RemoteWithExtrasException &amp;&amp; ((RemoteWithExtrasException) ioe)<a name="line.711"></a>
+<span class="sourceLineNo">712</span>              .unwrapRemoteException() instanceof NotServingRegionException)<a name="line.712"></a>
+<span class="sourceLineNo">713</span>        ) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>          // no need to retry again<a name="line.714"></a>
+<span class="sourceLineNo">715</span>          return;<a name="line.715"></a>
+<span class="sourceLineNo">716</span>        }<a name="line.716"></a>
+<span class="sourceLineNo">717</span>        LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(),<a name="line.717"></a>
+<span class="sourceLineNo">718</span>          ioe);<a name="line.718"></a>
+<span class="sourceLineNo">719</span>      }<a name="line.719"></a>
+<span class="sourceLineNo">720</span>      Thread.sleep(1000);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>    }<a name="line.721"></a>
+<span class="sourceLineNo">722</span>    throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout);<a name="line.722"></a>
+<span class="sourceLineNo">723</span>  }<a name="line.723"></a>
+<span class="sourceLineNo">724</span><a name="line.724"></a>
+<span class="sourceLineNo">725</span>  /**<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * Calculate min necessary to start. This is not an absolute. It is just a friction that will<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   * cause us hang around a bit longer waiting on RegionServers to check-in.<a name="line.727"></a>
+<span class="sourceLineNo">728</span>   */<a name="line.728"></a>
+<span class="sourceLineNo">729</span>  private int getMinToStart() {<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (master.isInMaintenanceMode()) {<a name="line.730"></a>
+<span class="sourceLineNo">731</span>      // If in maintenance mode, then in process region server hosting meta will be the only server<a name="line.731"></a>
+<span class="sourceLineNo">732</span>      // available<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return 1;<a name="line.733"></a>
+<span class="sourceLineNo">734</span>    }<a name="line.734"></a>
+<span class="sourceLineNo">735</span><a name="line.735"></a>
+<span class="sourceLineNo">736</span>    int minimumRequired = 1;<a name="line.736"></a>
+<span class="sourceLineNo">737</span>    int minToStart = this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MINTOSTART, -1);<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    // Ensure we are never less than minimumRequired else stuff won't work.<a name="line.738"></a>
+<span class="sourceLineNo">739</span>    return Math.max(minToStart, minimumRequired);<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  }<a name="line.740"></a>
+<span class="sourceLineNo">741</span><a name="line.741"></a>
+<span class="sourceLineNo">742</span>  /**<a name="line.742"></a>
+<span class="sourceLineNo">743</span>   * Wait for the region servers to report in. We will wait until one of this condition is met: -<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   * servers is reached - the 'hbase.master.wait.on.regionservers.mintostart' is reached AND there<a name="line.745"></a>
+<span class="sourceLineNo">746</span>   * have been no new region server in for 'hbase.master.wait.on.regionservers.interval' time AND<a name="line.746"></a>
+<span class="sourceLineNo">747</span>   * the 'hbase.master.wait.on.regionservers.timeout' is reached n<a name="line.747"></a>
+<span class="sourceLineNo">748</span>   */<a name="line.748"></a>
+<span class="sourceLineNo">749</span>  public void waitForRegionServers(MonitoredTask status) throws InterruptedException {<a name="line.749"></a>
+<span class="sourceLineNo">750</span>    final long interval =<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_INTERVAL, 1500);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>    final long timeout =<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_TIMEOUT, 4500);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    // Min is not an absolute; just a friction making us wait longer on server checkin.<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    int minToStart = getMinToStart();<a name="line.755"></a>
+<span class="sourceLineNo">756</span>    int maxToStart =<a name="line.756"></a>
+<span class="sourceLineNo">757</span>      this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MAXTOSTART, Integer.MAX_VALUE);<a name="line.757"></a>
+<span class="sourceLineNo">758</span>    if (maxToStart &lt; minToStart) {<a name="line.758"></a>
+<span class="sourceLineNo">759</span>      LOG.warn(String.format("The value of '%s' (%d) is set less than '%s' (%d), ignoring.",<a name="line.759"></a>
+<span class="sourceLineNo">760</span>        WAIT_ON_REGIONSERVERS_MAXTOSTART, maxToStart, WAIT_ON_REGIONSERVERS_MINTOSTART,<a name="line.760"></a>
+<span class="sourceLineNo">761</span>        minToStart));<a name="line.761"></a>
+<span class="sourceLineNo">762</span>      maxToStart = Integer.MAX_VALUE;<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    }<a name="line.763"></a>
+<span class="sourceLineNo">764</span><a name="line.764"></a>
+<span class="sourceLineNo">765</span>    long now = EnvironmentEdgeManager.currentTime();<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    final long startTime = now;<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    long slept = 0;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    long lastLogTime = 0;<a name="line.768"></a>
+<span class="sourceLineNo">769</span>    long lastCountChange = startTime;<a name="line.769"></a>
+<span class="sourceLineNo">770</span>    int count = countOfRegionServers();<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    int oldCount = 0;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    // This while test is a little hard to read. We try to comment it in below but in essence:<a name="line.772"></a>
+<span class="sourceLineNo">773</span>    // Wait if Master is not stopped and the number of regionservers that have checked-in is<a name="line.773"></a>
+<span class="sourceLineNo">774</span>    // less than the maxToStart. Both of these conditions will be true near universally.<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    // Next, we will keep cycling if ANY of the following three conditions are true:<a name="line.775"></a>
+<span class="sourceLineNo">776</span>    // 1. The time since a regionserver registered is &lt; interval (means servers are actively<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    // checking in).<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    // 2. We are under the total timeout.<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    // 3. The count of servers is &lt; minimum.<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    for (ServerListener listener : this.listeners) {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      listener.waiting();<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    while (<a name="line.783"></a>
+<span class="sourceLineNo">784</span>      !this.master.isStopped() &amp;&amp; !isClusterShutdown() &amp;&amp; count &lt; maxToStart<a name="line.784"></a>
+<span class="sourceLineNo">785</span>        &amp;&amp; ((lastCountChange + interval) &gt; now || timeout &gt; slept || count &lt; minToStart)<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    ) {<a name="line.786"></a>
+<span class="sourceLineNo">787</span>      // Log some info at every interval time or if there is a change<a name="line.787"></a>
+<span class="sourceLineNo">788</span>      if (oldCount != count || lastLogTime + interval &lt; now) {<a name="line.788"></a>
+<span class="sourceLineNo">789</span>        lastLogTime = now;<a name="line.789"></a>
+<span class="sourceLineNo">790</span>        String msg =<a name="line.790"></a>
+<span class="sourceLineNo">791</span>          "Waiting on regionserver count=" + count + "; waited=" + slept + "ms, expecting min="<a name="line.791"></a>
+<span class="sourceLineNo">792</span>            + minToStart + " server(s), max=" + getStrForMax(maxToStart) + " server(s), "<a name="line.792"></a>
+<span class="sourceLineNo">793</span>            + "timeout=" + timeout + "ms, lastChange=" + (now - lastCountChange) + "ms";<a name="line.793"></a>
+<span class="sourceLineNo">794</span>        LOG.info(msg);<a name="line.794"></a>
+<span class="sourceLineNo">795</span>        status.setStatus(msg);<a name="line.795"></a>
+<span class="sourceLineNo">796</span>      }<a name="line.796"></a>
+<span class="sourceLineNo">797</span><a name="line.797"></a>
+<span class="sourceLineNo">798</span>      // We sleep for some time<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      final long sleepTime = 50;<a name="line.799"></a>
+<span class="sourceLineNo">800</span>      Thread.sleep(sleepTime);<a name="line.800"></a>
+<span class="sourceLineNo">801</span>      now = EnvironmentEdgeManager.currentTime();<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      slept = now - startTime;<a name="line.802"></a>
+<span class="sourceLineNo">803</span><a name="line.803"></a>
+<span class="sourceLineNo">804</span>      oldCount = count;<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      count = countOfRegionServers();<a name="line.805"></a>
+<span class="sourceLineNo">806</span>      if (count != oldCount) {<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        lastCountChange = now;<a name="line.807"></a>
+<span class="sourceLineNo">808</span>      }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    }<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    // Did we exit the loop because cluster is going down?<a name="line.810"></a>
+<span class="sourceLineNo">811</span>    if (isClusterShutdown()) {<a name="line.811"></a>
+<span class="sourceLineNo">812</span>      this.master.stop("Cluster shutdown");<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    }<a name="line.813"></a>
+<span class="sourceLineNo">814</span>    LOG.info("Finished waiting on RegionServer count=" + count + "; waited=" + slept + "ms,"<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      + " expected min=" + minToStart + " server(s), max=" + getStrForMax(maxToStart)<a name="line.815"></a>
+<span class="sourceLineNo">816</span>      + " server(s)," + " master is " + (this.master.isStopped() ? "stopped." : "running"));<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  private String getStrForMax(final int max) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return max == Integer.MAX_VALUE ? "NO_LIMIT" : Integer.toString(max);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  /** Returns A copy of the internal list of online servers. */<a name="line.823"></a>
+<span class="sourceLineNo">824</span>  public List&lt;ServerName&gt; getOnlineServersList() {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    // TODO: optimize the load balancer call so we don't need to make a new list<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    // TODO: FIX. THIS IS POPULAR CALL.<a name="line.826"></a>
+<span class="sourceLineNo">827</span>    return new ArrayList&lt;&gt;(this.onlineServers.keySet());<a name="line.827"></a>
+<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>  /**<a name="line.830"></a>
+<span class="sourceLineNo">831</span>   * @param keys                 The target server name<a name="line.831"></a>
+<span class="sourceLineNo">832</span>   * @param idleServerPredicator Evaluates the server on the given load<a name="line.832"></a>
+<span class="sourceLineNo">833</span>   * @return A copy of the internal list of online servers matched by the predicator<a name="line.833"></a>
+<span class="sourceLineNo">834</span>   */<a name="line.834"></a>
+<span class="sourceLineNo">835</span>  public List&lt;ServerName&gt; getOnlineServersListWithPredicator(List&lt;ServerName&gt; keys,<a name="line.835"></a>
+<span class="sourceLineNo">836</span>    Predicate&lt;ServerMetrics&gt; idleServerPredicator) {<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    List&lt;ServerName&gt; names = new ArrayList&lt;&gt;();<a name="line.837"></a>
+<span class="sourceLineNo">838</span>    if (keys != null &amp;&amp; idleServerPredicator != null) {<a name="line.838"></a>
+<span class="sourceLineNo">839</span>      keys.forEach(name -&gt; {<a name="line.839"></a>
+<span class="sourceLineNo">840</span>        ServerMetrics load = onlineServers.get(name);<a name="line.840"></a>
+<span class="sourceLineNo">841</span>        if (load != null) {<a name="line.841"></a>
+<span class="sourceLineNo">842</span>          if (idleServerPredicator.test(load)) {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>            names.add(name);<a name="line.843"></a>
+<span class="sourceLineNo">844</span>          }<a name="line.844"></a>
+<span class="sourceLineNo">845</span>        }<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      });<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    }<a name="line.847"></a>
+<span class="sourceLineNo">848</span>    return names;<a name="line.848"></a>
 <span class="sourceLineNo">849</span>  }<a name="line.849"></a>
 <span class="sourceLineNo">850</span><a name="line.850"></a>
-<span class="sourceLineNo">851</span>  public boolean isServerOnline(ServerName serverName) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>    return serverName != null &amp;&amp; onlineServers.containsKey(serverName);<a name="line.852"></a>
-<span class="sourceLineNo">853</span>  }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>  public enum ServerLiveState {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>    LIVE,<a name="line.856"></a>
-<span class="sourceLineNo">857</span>    DEAD,<a name="line.857"></a>
-<span class="sourceLineNo">858</span>    UNKNOWN<a name="line.858"></a>
-<span class="sourceLineNo">859</span>  }<a name="line.859"></a>
-<span class="sourceLineNo">860</span><a name="line.860"></a>
-<span class="sourceLineNo">861</span>  /** Returns whether the server is online, dead, or unknown. */<a name="line.861"></a>
-<span class="sourceLineNo">862</span>  public synchronized ServerLiveState isServerKnownAndOnline(ServerName serverName) {<a name="line.862"></a>
-<span class="sourceLineNo">863</span>    return onlineServers.containsKey(serverName)<a name="line.863"></a>
-<span class="sourceLineNo">864</span>      ? ServerLiveState.LIVE<a name="line.864"></a>
-<span class="sourceLineNo">865</span>      : (deadservers.isDeadServer(serverName) ? ServerLiveState.DEAD : ServerLiveState.UNKNOWN);<a name="line.865"></a>
-<span class="sourceLineNo">866</span>  }<a name="line.866"></a>
-<span class="sourceLineNo">867</span><a name="line.867"></a>
-<span class="sourceLineNo">868</span>  /**<a name="line.868"></a>
-<span class="sourceLineNo">869</span>   * Check if a server is known to be dead. A server can be online, or known to be dead, or unknown<a name="line.869"></a>
-<span class="sourceLineNo">870</span>   * to this manager (i.e, not online, not known to be dead either; it is simply not tracked by the<a name="line.870"></a>
-<span class="sourceLineNo">871</span>   * master any more, for example, a very old previous instance).<a name="line.871"></a>
-<span class="sourceLineNo">872</span>   */<a name="line.872"></a>
-<span class="sourceLineNo">873</span>  public synchronized boolean isServerDead(ServerName serverName) {<a name="line.873"></a>
-<span class="sourceLineNo">874</span>    return serverName == null || deadservers.isDeadServer(serverName);<a name="line.874"></a>
-<span class="sourceLineNo">875</span>  }<a name="line.875"></a>
-<span class="sourceLineNo">876</span><a name="line.876"></a>
-<span class="sourceLineNo">877</span>  /**<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * Check if a server is unknown. A server can be online, or known to be dead, or unknown to this<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * manager (i.e, not online, not known to be dead either; it is simply not tracked by the master<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * any more, for example, a very old previous instance).<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public boolean isServerUnknown(ServerName serverName) {<a name="line.882"></a>
-<span class="sourceLineNo">883</span>    return serverName == null<a name="line.883"></a>
-<span class="sourceLineNo">884</span>      || (!onlineServers.containsKey(serverName) &amp;&amp; !deadservers.isDeadServer(serverName));<a name="line.884"></a>
-<span class="sourceLineNo">885</span>  }<a name="line.885"></a>
-<span class="sourceLineNo">886</span><a name="line.886"></a>
-<span class="sourceLineNo">887</span>  public void shutdownCluster() {<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    String statusStr = "Cluster shutdown requested of master=" + this.master.getServerName();<a name="line.888"></a>
-<span class="sourceLineNo">889</span>    LOG.info(statusStr);<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    this.clusterShutdown.set(true);<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    if (onlineServers.isEmpty()) {<a name="line.891"></a>
-<span class="sourceLineNo">892</span>      // we do not synchronize here so this may cause a double stop, but not a big deal<a name="line.892"></a>
-<span class="sourceLineNo">893</span>      master.stop("OnlineServer=0 right after cluster shutdown set");<a name="line.893"></a>
-<span class="sourceLineNo">894</span>    }<a name="line.894"></a>
-<span class="sourceLineNo">895</span>  }<a name="line.895"></a>
-<span class="sourceLineNo">896</span><a name="line.896"></a>
-<span class="sourceLineNo">897</span>  public boolean isClusterShutdown() {<a name="line.897"></a>
-<span class="sourceLineNo">898</span>    return this.clusterShutdown.get();<a name="line.898"></a>
-<span class="sourceLineNo">899</span>  }<a name="line.899"></a>
-<span class="sourceLineNo">900</span><a name="line.900"></a>
-<span class="sourceLineNo">901</span>  /**<a name="line.901"></a>
-<span class="sourceLineNo">902</span>   * start chore in ServerManager<a name="line.902"></a>
-<span class="sourceLineNo">903</span>   */<a name="line.903"></a>
-<span class="sourceLineNo">904</span>  public void startChore() {<a name="line.904"></a>
-<span class="sourceLineNo">905</span>    Configuration c = master.getConfiguration();<a name="line.905"></a>
-<span class="sourceLineNo">906</span>    if (persistFlushedSequenceId) {<a name="line.906"></a>
-<span class="sourceLineNo">907</span>      new Thread(() -&gt; {<a name="line.907"></a>
-<span class="sourceLineNo">908</span>        // after AM#loadMeta, RegionStates should be loaded, and some regions are<a name="line.908"></a>
-<span class="sourceLineNo">909</span>        // deleted by drop/split/merge during removeDeletedRegionFromLoadedFlushedSequenceIds,<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        // but these deleted regions are not added back to RegionStates,<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        // so we can safely remove deleted regions.<a name="line.911"></a>
-<span class="sourceLineNo">912</span>        removeDeletedRegionFromLoadedFlushedSequenceIds();<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      }, "RemoveDeletedRegionSyncThread").start();<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      int flushPeriod =<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        c.getInt(FLUSHEDSEQUENCEID_FLUSHER_INTERVAL, FLUSHEDSEQUENCEID_FLUSHER_INTERVAL_DEFAULT);<a name="line.915"></a>
-<span class="sourceLineNo">916</span>      flushedSeqIdFlusher = new FlushedSequenceIdFlusher("FlushedSequenceIdFlusher", flushPeriod);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      master.getChoreService().scheduleChore(flushedSeqIdFlusher);<a name="line.917"></a>
-<span class="sourceLineNo">918</span>    }<a name="line.918"></a>
-<span class="sourceLineNo">919</span>  }<a name="line.919"></a>
-<span class="sourceLineNo">920</span><a name="line.920"></a>
-<span class="sourceLineNo">921</span>  /**<a name="line.921"></a>
-<span class="sourceLineNo">922</span>   * Stop the ServerManager.<a name="line.922"></a>
-<span class="sourceLineNo">923</span>   */<a name="line.923"></a>
-<span class="sourceLineNo">924</span>  public void stop() {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>    if (flushedSeqIdFlusher != null) {<a name="line.925"></a>
-<span class="sourceLineNo">926</span>      flushedSeqIdFlusher.shutdown();<a name="line.926"></a>
-<span class="sourceLineNo">927</span>    }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    if (persistFlushedSequenceId) {<a name="line.928"></a>
-<span class="sourceLineNo">929</span>      try {<a name="line.929"></a>
-<span class="sourceLineNo">930</span>        persistRegionLastFlushedSequenceIds();<a name="line.930"></a>
-<span class="sourceLineNo">931</span>      } catch (IOException e) {<a name="line.931"></a>
-<span class="sourceLineNo">932</span>        LOG.warn("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.932"></a>
-<span class="sourceLineNo">933</span>      }<a name="line.933"></a>
-<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  }<a name="line.935"></a>
-<span class="sourceLineNo">936</span><a name="line.936"></a>
-<span class="sourceLineNo">937</span>  /**<a name="line.937"></a>
-<span class="sourceLineNo">938</span>   * Creates a list of possible destinations for a region. It contains the online servers, but not<a name="line.938"></a>
-<span class="sourceLineNo">939</span>   * the draining or dying servers.<a name="line.939"></a>
-<span class="sourceLineNo">940</span>   * @param serversToExclude can be null if there is no server to exclude<a name="line.940"></a>
-<span class="sourceLineNo">941</span>   */<a name="line.941"></a>
-<span class="sourceLineNo">942</span>  public List&lt;ServerName&gt; createDestinationServersList(final List&lt;ServerName&gt; serversToExclude) {<a name="line.942"></a>
-<span class="sourceLineNo">943</span>    Set&lt;ServerName&gt; destServers = new HashSet&lt;&gt;();<a name="line.943"></a>
-<span class="sourceLineNo">944</span>    onlineServers.forEach((sn, sm) -&gt; {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>      if (sm.getLastReportTimestamp() &gt; 0) {<a name="line.945"></a>
-<span class="sourceLineNo">946</span>        // This means we have already called regionServerReport at leaset once, then let's include<a name="line.946"></a>
-<span class="sourceLineNo">947</span>        // this server for region assignment. This is an optimization to avoid assigning regions to<a name="line.947"></a>
-<span class="sourceLineNo">948</span>        // an uninitialized server. See HBASE-25032 for more details.<a name="line.948"></a>
-<span class="sourceLineNo">949</span>        destServers.add(sn);<a name="line.949"></a>
-<span class="sourceLineNo">950</span>      }<a name="line.950"></a>
-<span class="sourceLineNo">951</span>    });<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>    if (serversToExclude != null) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>      destServers.removeAll(serversToExclude);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    }<a name="line.955"></a>
-<span class="sourceLineNo">956</span><a name="line.956"></a>
-<span class="sourceLineNo">957</span>    // Loop through the draining server list and remove them from the server list<a name="line.957"></a>
-<span class="sourceLineNo">958</span>    final List&lt;ServerName&gt; drainingServersCopy = getDrainingServersList();<a name="line.958"></a>
-<span class="sourceLineNo">959</span>    destServers.removeAll(drainingServersCopy);<a name="line.959"></a>
-<span class="sourceLineNo">960</span><a name="line.960"></a>
-<span class="sourceLineNo">961</span>    return new ArrayList&lt;&gt;(destServers);<a name="line.961"></a>
-<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
-<span class="sourceLineNo">963</span><a name="line.963"></a>
-<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
-<span class="sourceLineNo">965</span>   * Calls {@link #createDestinationServersList} without server to exclude.<a name="line.965"></a>
-<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public List&lt;ServerName&gt; createDestinationServersList() {<a name="line.967"></a>
-<span class="sourceLineNo">968</span>    return createDestinationServersList(null);<a name="line.968"></a>
-<span class="sourceLineNo">969</span>  }<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>  /**<a name="line.971"></a>
-<span class="sourceLineNo">972</span>   * To clear any dead server with same host name and port of any online server<a name="line.972"></a>
-<span class="sourceLineNo">973</span>   */<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  void clearDeadServersWithSameHostNameAndPortOfOnlineServer() {<a name="line.974"></a>
-<span class="sourceLineNo">975</span>    for (ServerName serverName : getOnlineServersList()) {<a name="line.975"></a>
-<span class="sourceLineNo">976</span>      deadservers.cleanAllPreviousInstances(serverName);<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    }<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public void removeRegion(final RegionInfo regionInfo) {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    final byte[] encodedName = regionInfo.getEncodedNameAsBytes();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>    storeFlushedSequenceIdsByRegion.remove(encodedName);<a name="line.985"></a>
-<span class="sourceLineNo">986</span>    flushedSequenceIdByRegion.remove(encodedName);<a name="line.986"></a>
-<span class="sourceLineNo">987</span>  }<a name="line.987"></a>
-<span class="sourceLineNo">988</span><a name="line.988"></a>
-<span class="sourceLineNo">989</span>  public boolean isRegionInServerManagerStates(final RegionInfo hri) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>    final byte[] encodedName = hri.getEncodedNameAsBytes();<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    return (storeFlushedSequenceIdsByRegion.containsKey(encodedName)<a name="line.991"></a>
-<span class="sourceLineNo">992</span>      || flushedSequenceIdByRegion.containsKey(encodedName));<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  /**<a name="line.995"></a>
-<span class="sourceLineNo">996</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.996"></a>
-<span class="sourceLineNo">997</span>   */<a name="line.997"></a>
-<span class="sourceLineNo">998</span>  public void removeRegions(final List&lt;RegionInfo&gt; regions) {<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    for (RegionInfo hri : regions) {<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>      removeRegion(hri);<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>    }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span>  }<a name="line.1002"></a>
-<span class="sourceLineNo">1003</span><a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  /**<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>   * May return 0 when server is not online.<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>   */<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public int getVersionNumber(ServerName serverName) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    return serverMetrics != null ? serverMetrics.getVersionNumber() : 0;<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  /**<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>   * May return "0.0.0" when server is not online<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>   */<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  public String getVersion(ServerName serverName) {<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>    return serverMetrics != null ? serverMetrics.getVersion() : "0.0.0";<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  }<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span><a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public int getInfoPort(ServerName serverName) {<a name="line.1020"></a>
+<span class="sourceLineNo">851</span>  /** Returns A copy of the internal list of draining servers. */<a name="line.851"></a>
+<span class="sourceLineNo">852</span>  public List&lt;ServerName&gt; getDrainingServersList() {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>    return new ArrayList&lt;&gt;(this.drainingServers);<a name="line.853"></a>
+<span class="sourceLineNo">854</span>  }<a name="line.854"></a>
+<span class="sourceLineNo">855</span><a name="line.855"></a>
+<span class="sourceLineNo">856</span>  public boolean isServerOnline(ServerName serverName) {<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    return serverName != null &amp;&amp; onlineServers.containsKey(serverName);<a name="line.857"></a>
+<span class="sourceLineNo">858</span>  }<a name="line.858"></a>
+<span class="sourceLineNo">859</span><a name="line.859"></a>
+<span class="sourceLineNo">860</span>  public enum ServerLiveState {<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    LIVE,<a name="line.861"></a>
+<span class="sourceLineNo">862</span>    DEAD,<a name="line.862"></a>
+<span class="sourceLineNo">863</span>    UNKNOWN<a name="line.863"></a>
+<span class="sourceLineNo">864</span>  }<a name="line.864"></a>
+<span class="sourceLineNo">865</span><a name="line.865"></a>
+<span class="sourceLineNo">866</span>  /** Returns whether the server is online, dead, or unknown. */<a name="line.866"></a>
+<span class="sourceLineNo">867</span>  public synchronized ServerLiveState isServerKnownAndOnline(ServerName serverName) {<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    return onlineServers.containsKey(serverName)<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      ? ServerLiveState.LIVE<a name="line.869"></a>
+<span class="sourceLineNo">870</span>      : (deadservers.isDeadServer(serverName) ? ServerLiveState.DEAD : ServerLiveState.UNKNOWN);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>  }<a name="line.871"></a>
+<span class="sourceLineNo">872</span><a name="line.872"></a>
+<span class="sourceLineNo">873</span>  /**<a name="line.873"></a>
+<span class="sourceLineNo">874</span>   * Check if a server is known to be dead. A server can be online, or known to be dead, or unknown<a name="line.874"></a>
+<span class="sourceLineNo">875</span>   * to this manager (i.e, not online, not known to be dead either; it is simply not tracked by the<a name="line.875"></a>
+<span class="sourceLineNo">876</span>   * master any more, for example, a very old previous instance).<a name="line.876"></a>
+<span class="sourceLineNo">877</span>   */<a name="line.877"></a>
+<span class="sourceLineNo">878</span>  public synchronized boolean isServerDead(ServerName serverName) {<a name="line.878"></a>
+<span class="sourceLineNo">879</span>    return serverName == null || deadservers.isDeadServer(serverName);<a name="line.879"></a>
+<span class="sourceLineNo">880</span>  }<a name="line.880"></a>
+<span class="sourceLineNo">881</span><a name="line.881"></a>
+<span class="sourceLineNo">882</span>  /**<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * Check if a server is unknown. A server can be online, or known to be dead, or unknown to this<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * manager (i.e, not online, not known to be dead either; it is simply not tracked by the master<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * any more, for example, a very old previous instance).<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   */<a name="line.886"></a>
+<span class="sourceLineNo">887</span>  public boolean isServerUnknown(ServerName serverName) {<a name="line.887"></a>
+<span class="sourceLineNo">888</span>    return serverName == null<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      || (!onlineServers.containsKey(serverName) &amp;&amp; !deadservers.isDeadServer(serverName));<a name="line.889"></a>
+<span class="sourceLineNo">890</span>  }<a name="line.890"></a>
+<span class="sourceLineNo">891</span><a name="line.891"></a>
+<span class="sourceLineNo">892</span>  public void shutdownCluster() {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>    String statusStr = "Cluster shutdown requested of master=" + this.master.getServerName();<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    LOG.info(statusStr);<a name="line.894"></a>
+<span class="sourceLineNo">895</span>    this.clusterShutdown.set(true);<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    if (onlineServers.isEmpty()) {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      // we do not synchronize here so this may cause a double stop, but not a big deal<a name="line.897"></a>
+<span class="sourceLineNo">898</span>      master.stop("OnlineServer=0 right after cluster shutdown set");<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    }<a name="line.899"></a>
+<span class="sourceLineNo">900</span>  }<a name="line.900"></a>
+<span class="sourceLineNo">901</span><a name="line.901"></a>
+<span class="sourceLineNo">902</span>  public boolean isClusterShutdown() {<a name="line.902"></a>
+<span class="sourceLineNo">903</span>    return this.clusterShutdown.get();<a name="line.903"></a>
+<span class="sourceLineNo">904</span>  }<a name="line.904"></a>
+<span class="sourceLineNo">905</span><a name="line.905"></a>
+<span class="sourceLineNo">906</span>  /**<a name="line.906"></a>
+<span class="sourceLineNo">907</span>   * start chore in ServerManager<a name="line.907"></a>
+<span class="sourceLineNo">908</span>   */<a name="line.908"></a>
+<span class="sourceLineNo">909</span>  public void startChore() {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>    Configuration c = master.getConfiguration();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>    if (persistFlushedSequenceId) {<a name="line.911"></a>
+<span class="sourceLineNo">912</span>      new Thread(() -&gt; {<a name="line.912"></a>
+<span class="sourceLineNo">913</span>        // after AM#loadMeta, RegionStates should be loaded, and some regions are<a name="line.913"></a>
+<span class="sourceLineNo">914</span>        // deleted by drop/split/merge during removeDeletedRegionFromLoadedFlushedSequenceIds,<a name="line.914"></a>
+<span class="sourceLineNo">915</span>        // but these deleted regions are not added back to RegionStates,<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        // so we can safely remove deleted regions.<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        removeDeletedRegionFromLoadedFlushedSequenceIds();<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }, "RemoveDeletedRegionSyncThread").start();<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      int flushPeriod =<a name="line.919"></a>
+<span class="sourceLineNo">920</span>        c.getInt(FLUSHEDSEQUENCEID_FLUSHER_INTERVAL, FLUSHEDSEQUENCEID_FLUSHER_INTERVAL_DEFAULT);<a name="line.920"></a>
+<span class="sourceLineNo">921</span>      flushedSeqIdFlusher = new FlushedSequenceIdFlusher("FlushedSequenceIdFlusher", flushPeriod);<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      master.getChoreService().scheduleChore(flushedSeqIdFlusher);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>    }<a name="line.923"></a>
+<span class="sourceLineNo">924</span>  }<a name="line.924"></a>
+<span class="sourceLineNo">925</span><a name="line.925"></a>
+<span class="sourceLineNo">926</span>  /**<a name="line.926"></a>
+<span class="sourceLineNo">927</span>   * Stop the ServerManager.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>   */<a name="line.928"></a>
+<span class="sourceLineNo">929</span>  public void stop() {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>    if (flushedSeqIdFlusher != null) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>      flushedSeqIdFlusher.shutdown();<a name="line.931"></a>
+<span class="sourceLineNo">932</span>    }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>    if (persistFlushedSequenceId) {<a name="line.933"></a>
+<span class="sourceLineNo">934</span>      try {<a name="line.934"></a>
+<span class="sourceLineNo">935</span>        persistRegionLastFlushedSequenceIds();<a name="line.935"></a>
+<span class="sourceLineNo">936</span>      } catch (IOException e) {<a name="line.936"></a>
+<span class="sourceLineNo">937</span>        LOG.warn("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.937"></a>
+<span class="sourceLineNo">938</span>      }<a name="line.938"></a>
+<span class="sourceLineNo">939</span>    }<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  }<a name="line.940"></a>
+<span class="sourceLineNo">941</span><a name="line.941"></a>
+<span class="sourceLineNo">942</span>  /**<a name="line.942"></a>
+<span class="sourceLineNo">943</span>   * Creates a list of possible destinations for a region. It contains the online servers, but not<a name="line.943"></a>
+<span class="sourceLineNo">944</span>   * the draining or dying servers.<a name="line.944"></a>
+<span class="sourceLineNo">945</span>   * @param serversToExclude can be null if there is no server to exclude<a name="line.945"></a>
+<span class="sourceLineNo">946</span>   */<a name="line.946"></a>
+<span class="sourceLineNo">947</span>  public List&lt;ServerName&gt; createDestinationServersList(final List&lt;ServerName&gt; serversToExclude) {<a name="line.947"></a>
+<span class="sourceLineNo">948</span>    Set&lt;ServerName&gt; destServers = new HashSet&lt;&gt;();<a name="line.948"></a>
+<span class="sourceLineNo">949</span>    onlineServers.forEach((sn, sm) -&gt; {<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      if (sm.getLastReportTimestamp() &gt; 0) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>        // This means we have already called regionServerReport at leaset once, then let's include<a name="line.951"></a>
+<span class="sourceLineNo">952</span>        // this server for region assignment. This is an optimization to avoid assigning regions to<a name="line.952"></a>
+<span class="sourceLineNo">953</span>        // an uninitialized server. See HBASE-25032 for more details.<a name="line.953"></a>
+<span class="sourceLineNo">954</span>        destServers.add(sn);<a name="line.954"></a>
+<span class="sourceLineNo">955</span>      }<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    });<a name="line.956"></a>
+<span class="sourceLineNo">957</span><a name="line.957"></a>
+<span class="sourceLineNo">958</span>    if (serversToExclude != null) {<a name="line.958"></a>
+<span class="sourceLineNo">959</span>      destServers.removeAll(serversToExclude);<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    }<a name="line.960"></a>
+<span class="sourceLineNo">961</span><a name="line.961"></a>
+<span class="sourceLineNo">962</span>    // Loop through the draining server list and remove them from the server list<a name="line.962"></a>
+<span class="sourceLineNo">963</span>    final List&lt;ServerName&gt; drainingServersCopy = getDrainingServersList();<a name="line.963"></a>
+<span class="sourceLineNo">964</span>    destServers.removeAll(drainingServersCopy);<a name="line.964"></a>
+<span class="sourceLineNo">965</span><a name="line.965"></a>
+<span class="sourceLineNo">966</span>    return new ArrayList&lt;&gt;(destServers);<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  }<a name="line.967"></a>
+<span class="sourceLineNo">968</span><a name="line.968"></a>
+<span class="sourceLineNo">969</span>  /**<a name="line.969"></a>
+<span class="sourceLineNo">970</span>   * Calls {@link #createDestinationServersList} without server to exclude.<a name="line.970"></a>
+<span class="sourceLineNo">971</span>   */<a name="line.971"></a>
+<span class="sourceLineNo">972</span>  public List&lt;ServerName&gt; createDestinationServersList() {<a name="line.972"></a>
+<span class="sourceLineNo">973</span>    return createDestinationServersList(null);<a name="line.973"></a>
+<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
+<span class="sourceLineNo">975</span><a name="line.975"></a>
+<span class="sourceLineNo">976</span>  /**<a name="line.976"></a>
+<span class="sourceLineNo">977</span>   * To clear any dead server with same host name and port of any online server<a name="line.977"></a>
+<span class="sourceLineNo">978</span>   */<a name="line.978"></a>
+<span class="sourceLineNo">979</span>  void clearDeadServersWithSameHostNameAndPortOfOnlineServer() {<a name="line.979"></a>
+<span class="sourceLineNo">980</span>    for (ServerName serverName : getOnlineServersList()) {<a name="line.980"></a>
+<span class="sourceLineNo">981</span>      deadservers.cleanAllPreviousInstances(serverName);<a name="line.981"></a>
+<span class="sourceLineNo">982</span>    }<a name="line.982"></a>
+<span class="sourceLineNo">983</span>  }<a name="line.983"></a>
+<span class="sourceLineNo">984</span><a name="line.984"></a>
+<span class="sourceLineNo">985</span>  /**<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   */<a name="line.987"></a>
+<span class="sourceLineNo">988</span>  public void removeRegion(final RegionInfo regionInfo) {<a name="line.988"></a>
+<span class="sourceLineNo">989</span>    final byte[] encodedName = regionInfo.getEncodedNameAsBytes();<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    storeFlushedSequenceIdsByRegion.remove(encodedName);<a name="line.990"></a>
+<span class="sourceLineNo">991</span>    flushedSequenceIdByRegion.remove(encodedName);<a name="line.991"></a>
+<span class="sourceLineNo">992</span>  }<a name="line.992"></a>
+<span class="sourceLineNo">993</span><a name="line.993"></a>
+<span class="sourceLineNo">994</span>  public boolean isRegionInServerManagerStates(final RegionInfo hri) {<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    final byte[] encodedName = hri.getEncodedNameAsBytes();<a name="line.995"></a>
+<span class="sourceLineNo">996</span>    return (storeFlushedSequenceIdsByRegion.containsKey(encodedName)<a name="line.996"></a>
+<span class="sourceLineNo">997</span>      || flushedSequenceIdByRegion.containsKey(encodedName));<a name="line.997"></a>
+<span class="sourceLineNo">998</span>  }<a name="line.998"></a>
+<span class="sourceLineNo">999</span><a name="line.999"></a>
+<span class="sourceLineNo">1000</span>  /**<a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>   */<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>  public void removeRegions(final List&lt;RegionInfo&gt; regions) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>    for (RegionInfo hri : regions) {<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>      removeRegion(hri);<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    }<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  /**<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>   * May return 0 when server is not online.<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>   */<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  public int getVersionNumber(ServerName serverName) {<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    return serverMetrics != null ? serverMetrics.getVersionNumber() : 0;<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span><a name="line.1016"></a>
+<span class="sourceLineNo">1017</span>  /**<a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>   * May return "0.0.0" when server is not online<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>   */<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>  public String getVersion(ServerName serverName) {<a name="line.1020"></a>
 <span class="sourceLineNo">1021</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1021"></a>
-<span class="sourceLineNo">1022</span>    return serverMetrics != null ? serverMetrics.getInfoServerPort() : 0;<a name="line.1022"></a>
+<span class="sourceLineNo">1022</span>    return serverMetrics != null ? serverMetrics.getVersion() : "0.0.0";<a name="line.1022"></a>
 <span class="sourceLineNo">1023</span>  }<a name="line.1023"></a>
 <span class="sourceLineNo">1024</span><a name="line.1024"></a>
-<span class="sourceLineNo">1025</span>  /**<a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>   * Persist last flushed sequence id of each region to HDFS<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>   * @throws IOException if persit to HDFS fails<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>   */<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span>  private void persistRegionLastFlushedSequenceIds() throws IOException {<a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    if (isFlushSeqIdPersistInProgress) {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span>    isFlushSeqIdPersistInProgress = true;<a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    try {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      Configuration conf = master.getConfiguration();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>      Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span>      Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>      FileSystem fs = FileSystem.get(conf);<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      if (fs.exists(lastFlushedSeqIdPath)) {<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>        LOG.info("Rewriting .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span>        if (!fs.delete(lastFlushedSeqIdPath, false)) {<a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>          throw new IOException("Unable to remove existing " + lastFlushedSeqIdPath);<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>        }<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>      } else {<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span>        LOG.info("Writing .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>      }<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      FSDataOutputStream out = fs.create(lastFlushedSeqIdPath);<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>      FlushedSequenceId.Builder flushedSequenceIdBuilder = FlushedSequenceId.newBuilder();<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span>      try {<a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>        for (Entry&lt;byte[], Long&gt; entry : flushedSequenceIdByRegion.entrySet()) {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>          FlushedRegionSequenceId.Builder flushedRegionSequenceIdBuilder =<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>            FlushedRegionSequenceId.newBuilder();<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>          flushedRegionSequenceIdBuilder.setRegionEncodedName(ByteString.copyFrom(entry.getKey()));<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span>          flushedRegionSequenceIdBuilder.setSeqId(entry.getValue());<a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeSeqIds =<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>            storeFlushedSequenceIdsByRegion.get(entry.getKey());<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>          if (storeSeqIds != null) {<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>            for (Entry&lt;byte[], Long&gt; store : storeSeqIds.entrySet()) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>              FlushedStoreSequenceId.Builder flushedStoreSequenceIdBuilder =<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>                FlushedStoreSequenceId.newBuilder();<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>              flushedStoreSequenceIdBuilder.setFamily(ByteString.copyFrom(store.getKey()));<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>              flushedStoreSequenceIdBuilder.setSeqId(store.getValue());<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>              flushedRegionSequenceIdBuilder.addStores(flushedStoreSequenceIdBuilder);<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>            }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span>          }<a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>          flushedSequenceIdBuilder.addRegionSequenceId(flushedRegionSequenceIdBuilder);<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>        }<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>        flushedSequenceIdBuilder.build().writeDelimitedTo(out);<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span>      } finally {<a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>        if (out != null) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>          out.close();<a name="line.1071"></a>
+<span class="sourceLineNo">1025</span>  public int getInfoPort(ServerName serverName) {<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    return serverMetrics != null ? serverMetrics.getInfoServerPort() : 0;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span>  }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span><a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>  /**<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span>   * Persist last flushed sequence id of each region to HDFS<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>   * @throws IOException if persit to HDFS fails<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>   */<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>  private void persistRegionLastFlushedSequenceIds() throws IOException {<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span>    if (isFlushSeqIdPersistInProgress) {<a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>      return;<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>    }<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    isFlushSeqIdPersistInProgress = true;<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span>    try {<a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>      Configuration conf = master.getConfiguration();<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>      Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span>      FileSystem fs = FileSystem.get(conf);<a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>      if (fs.exists(lastFlushedSeqIdPath)) {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>        LOG.info("Rewriting .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>        if (!fs.delete(lastFlushedSeqIdPath, false)) {<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span>          throw new IOException("Unable to remove existing " + lastFlushedSeqIdPath);<a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>        }<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      } else {<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>        LOG.info("Writing .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span>      }<a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>      FSDataOutputStream out = fs.create(lastFlushedSeqIdPath);<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      FlushedSequenceId.Builder flushedSequenceIdBuilder = FlushedSequenceId.newBuilder();<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>      try {<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span>        for (Entry&lt;byte[], Long&gt; entry : flushedSequenceIdByRegion.entrySet()) {<a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>          FlushedRegionSequenceId.Builder flushedRegionSequenceIdBuilder =<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>            FlushedRegionSequenceId.newBuilder();<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>          flushedRegionSequenceIdBuilder.setRegionEncodedName(ByteString.copyFrom(entry.getKey()));<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>          flushedRegionSequenceIdBuilder.setSeqId(entry.getValue());<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeSeqIds =<a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>            storeFlushedSequenceIdsByRegion.get(entry.getKey());<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>          if (storeSeqIds != null) {<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>            for (Entry&lt;byte[], Long&gt; store : storeSeqIds.entrySet()) {<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>              FlushedStoreSequenceId.Builder flushedStoreSequenceIdBuilder =<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>                FlushedStoreSequenceId.newBuilder();<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>              flushedStoreSequenceIdBuilder.setFamily(ByteString.copyFrom(store.getKey()));<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>              flushedStoreSequenceIdBuilder.setSeqId(store.getValue());<a name="line.1067"></a>
+<span class="sourceLineNo">1068</span>              flushedRegionSequenceIdBuilder.addStores(flushedStoreSequenceIdBuilder);<a name="line.1068"></a>
+<span class="sourceLineNo">1069</span>            }<a name="line.1069"></a>
+<span class="sourceLineNo">1070</span>          }<a name="line.1070"></a>
+<span class="sourceLineNo">1071</span>          flushedSequenceIdBuilder.addRegionSequenceId(flushedRegionSequenceIdBuilder);<a name="line.1071"></a>
 <span class="sourceLineNo">1072</span>        }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span>      }<a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>    } finally {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>      isFlushSeqIdPersistInProgress = false;<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span>    }<a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>  }<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span><a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>  /**<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>   * Load last flushed sequence id of each region from HDFS, if persisted<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>   */<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  public void loadLastFlushedSequenceIds() throws IOException {<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span>    if (!persistFlushedSequenceId) {<a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>      return;<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>    }<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>    Configuration conf = master.getConfiguration();<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span>    Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>    Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>    FileSystem fs = FileSystem.get(conf);<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>    if (!fs.exists(lastFlushedSeqIdPath)) {<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>      LOG.info("No .lastflushedseqids found at " + lastFlushedSeqIdPath<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>        + " will record last flushed sequence id"<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>        + " for regions by regionserver report all over again");<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>      return;<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    } else {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      LOG.info("begin to load .lastflushedseqids at " + lastFlushedSeqIdPath);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>    }<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>    FSDataInputStream in = fs.open(lastFlushedSeqIdPath);<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    try {<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>      FlushedSequenceId flushedSequenceId = FlushedSequenceId.parseDelimitedFrom(in);<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>      if (flushedSequenceId == null) {<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span>        LOG.info(".lastflushedseqids found at {} is empty", lastFlushedSeqIdPath);<a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>        return;<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>      }<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>      for (FlushedRegionSequenceId flushedRegionSequenceId : flushedSequenceId<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>        .getRegionSequenceIdList()) {<a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>        byte[] encodedRegionName = flushedRegionSequenceId.getRegionEncodedName().toByteArray();<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>        flushedSequenceIdByRegion.putIfAbsent(encodedRegionName,<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>          flushedRegionSequenceId.getSeqId());<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>        if (<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>          flushedRegionSequenceId.getStoresList() != null<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>            &amp;&amp; flushedRegionSequenceId.getStoresList().size() != 0<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>        ) {<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>            computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>              () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>          for (FlushedStoreSequenceId flushedStoreSequenceId : flushedRegionSequenceId<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>            .getStoresList()) {<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>            storeFlushedSequenceId.put(flushedStoreSequenceId.getFamily().toByteArray(),<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>              flushedStoreSequenceId.getSeqId());<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>          }<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>        }<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>      }<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    } finally {<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>      in.close();<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>    }<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span>  }<a name="line.1127"></a>
-<span class="sourceLineNo">1128</span><a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>  /**<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>   * Regions may have been removed between latest persist of FlushedSequenceIds and master abort. So<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>   * after loading FlushedSequenceIds from file, and after meta loaded, we need to remove the<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>   * deleted region according to RegionStates.<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>   */<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>  public void removeDeletedRegionFromLoadedFlushedSequenceIds() {<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>    RegionStates regionStates = master.getAssignmentManager().getRegionStates();<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>    Iterator&lt;byte[]&gt; it = flushedSequenceIdByRegion.keySet().iterator();<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>    while (it.hasNext()) {<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>      byte[] regionEncodedName = it.next();<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>      if (regionStates.getRegionState(Bytes.toStringBinary(regionEncodedName)) == null) {<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>        it.remove();<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span>        storeFlushedSequenceIdsByRegion.remove(regionEncodedName);<a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>      }<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span>    }<a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  }<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span><a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>  private class FlushedSequenceIdFlusher extends ScheduledChore {<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span><a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>    public FlushedSequenceIdFlusher(String name, int p) {<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>      super(name, master, p, 60 * 1000); // delay one minute before first execute<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>    }<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span><a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    @Override<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>    protected void chore() {<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>      try {<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>        persistRegionLastFlushedSequenceIds();<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>      } catch (IOException e) {<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span>        LOG.debug("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>      }<a name="line.1158"></a>
-<span class="sourceLineNo">1159</span>    }<a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>  }<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>}<a name="line.1161"></a>
+<span class="sourceLineNo">1073</span>        flushedSequenceIdBuilder.build().writeDelimitedTo(out);<a name="line.1073"></a>
+<span class="sourceLineNo">1074</span>      } finally {<a name="line.1074"></a>
+<span class="sourceLineNo">1075</span>        if (out != null) {<a name="line.1075"></a>
+<span class="sourceLineNo">1076</span>          out.close();<a name="line.1076"></a>
+<span class="sourceLineNo">1077</span>        }<a name="line.1077"></a>
+<span class="sourceLineNo">1078</span>      }<a name="line.1078"></a>
+<span class="sourceLineNo">1079</span>    } finally {<a name="line.1079"></a>
+<span class="sourceLineNo">1080</span>      isFlushSeqIdPersistInProgress = false;<a name="line.1080"></a>
+<span class="sourceLineNo">1081</span>    }<a name="line.1081"></a>
+<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
+<span class="sourceLineNo">1083</span><a name="line.1083"></a>
+<span class="sourceLineNo">1084</span>  /**<a name="line.1084"></a>
+<span class="sourceLineNo">1085</span>   * Load last flushed sequence id of each region from HDFS, if persisted<a name="line.1085"></a>
+<span class="sourceLineNo">1086</span>   */<a name="line.1086"></a>
+<span class="sourceLineNo">1087</span>  public void loadLastFlushedSequenceIds() throws IOException {<a name="line.1087"></a>
+<span class="sourceLineNo">1088</span>    if (!persistFlushedSequenceId) {<a name="line.1088"></a>
+<span class="sourceLineNo">1089</span>      return;<a name="line.1089"></a>
+<span class="sourceLineNo">1090</span>    }<a name="line.1090"></a>
+<span class="sourceLineNo">1091</span>    Configuration conf = master.getConfiguration();<a name="line.1091"></a>
+<span class="sourceLineNo">1092</span>    Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1092"></a>
+<span class="sourceLineNo">1093</span>    Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1093"></a>
+<span class="sourceLineNo">1094</span>    FileSystem fs = FileSystem.get(conf);<a name="line.1094"></a>
+<span class="sourceLineNo">1095</span>    if (!fs.exists(lastFlushedSeqIdPath)) {<a name="line.1095"></a>
+<span class="sourceLineNo">1096</span>      LOG.info("No .lastflushedseqids found at " + lastFlushedSeqIdPath<a name="line.1096"></a>
+<span class="sourceLineNo">1097</span>        + " will record last flushed sequence id"<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span>        + " for regions by regionserver report all over again");<a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>      return;<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span>    } else {<a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>      LOG.info("begin to load .lastflushedseqids at " + lastFlushedSeqIdPath);<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>    }<a name="line.1102"></a>
+<span class="sourceLineNo">1103</span>    FSDataInputStream in = fs.open(lastFlushedSeqIdPath);<a name="line.1103"></a>
+<span class="sourceLineNo">1104</span>    try {<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>      FlushedSequenceId flushedSequenceId = FlushedSequenceId.parseDelimitedFrom(in);<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>      if (flushedSequenceId == null) {<a name="line.1106"></a>
+<span class="sourceLineNo">1107</span>        LOG.info(".lastflushedseqids found at {} is empty", lastFlushedSeqIdPath);<a name="line.1107"></a>
+<span class="sourceLineNo">1108</span>        return;<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span>      }<a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>      for (FlushedRegionSequenceId flushedRegionSequenceId : flushedSequenceId<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>        .getRegionSequenceIdList()) {<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>        byte[] encodedRegionName = flushedRegionSequenceId.getRegionEncodedName().toByteArray();<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>        flushedSequenceIdByRegion.putIfAbsent(encodedRegionName,<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>          flushedRegionSequenceId.getSeqId());<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>        if (<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>          flushedRegionSequenceId.getStoresList() != null<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span>            &amp;&amp; flushedRegionSequenceId.getStoresList().size() != 0<a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>        ) {<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>            computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span>              () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>          for (FlushedStoreSequenceId flushedStoreSequenceId : flushedRegionSequenceId<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>            .getStoresList()) {<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>            storeFlushedSequenceId.put(flushedStoreSequenceId.getFamily().toByteArray(),<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>              flushedStoreSequenceId.getSeqId());<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>          }<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>        }<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>      }<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span>    } finally {<a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>      in.close();<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>    }<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>  }<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span><a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>  /**<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>   * Regions may have been removed between latest persist of FlushedSequenceIds and master abort. So<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>   * after loading FlushedSequenceIds from file, and after meta loaded, we need to remove the<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>   * deleted region according to RegionStates.<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>   */<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>  public void removeDeletedRegionFromLoadedFlushedSequenceIds() {<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>    RegionStates regionStates = master.getAssignmentManager().getRegionStates();<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span>    Iterator&lt;byte[]&gt; it = flushedSequenceIdByRegion.keySet().iterator();<a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>    while (it.hasNext()) {<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span>      byte[] regionEncodedName = it.next();<a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>      if (regionStates.getRegionState(Bytes.toStringBinary(regionEncodedName)) == null) {<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>        it.remove();<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>        storeFlushedSequenceIdsByRegion.remove(regionEncodedName);<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span>      }<a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>    }<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>  }<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span><a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>  private class FlushedSequenceIdFlusher extends ScheduledChore {<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span><a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    public FlushedSequenceIdFlusher(String name, int p) {<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>      super(name, master, p, 60 * 1000); // delay one minute before first execute<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>    }<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span><a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>    @Override<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>    protected void chore() {<a name="line.1158"></a>
+<span class="sourceLineNo">1159</span>      try {<a name="line.1159"></a>
+<span class="sourceLineNo">1160</span>        persistRegionLastFlushedSequenceIds();<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span>      } catch (IOException e) {<a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>        LOG.debug("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>      }<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span>    }<a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>  }<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>}<a name="line.1166"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html
index 140134dec90..89e1e0e9915 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.ServerLiveState.html
@@ -227,946 +227,951 @@
 <span class="sourceLineNo">219</span>    // in, it should have been removed from serverAddressToServerInfo and queued<a name="line.219"></a>
 <span class="sourceLineNo">220</span>    // for processing by ProcessServerShutdown.<a name="line.220"></a>
 <span class="sourceLineNo">221</span><a name="line.221"></a>
-<span class="sourceLineNo">222</span>    final String hostname =<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      request.hasUseThisHostnameInstead() ? request.getUseThisHostnameInstead() : ia.getHostName();<a name="line.223"></a>
-<span class="sourceLineNo">224</span>    ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());<a name="line.224"></a>
-<span class="sourceLineNo">225</span>    checkClockSkew(sn, request.getServerCurrentTime());<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    checkIsDead(sn, "STARTUP");<a name="line.226"></a>
-<span class="sourceLineNo">227</span>    if (!checkAndRecordNewServer(sn, ServerMetricsBuilder.of(sn, versionNumber, version))) {<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      LOG.warn(<a name="line.228"></a>
-<span class="sourceLineNo">229</span>        "THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    }<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    storage.started(sn);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    return sn;<a name="line.232"></a>
-<span class="sourceLineNo">233</span>  }<a name="line.233"></a>
-<span class="sourceLineNo">234</span><a name="line.234"></a>
-<span class="sourceLineNo">235</span>  /**<a name="line.235"></a>
-<span class="sourceLineNo">236</span>   * Updates last flushed sequence Ids for the regions on server sn<a name="line.236"></a>
-<span class="sourceLineNo">237</span>   */<a name="line.237"></a>
-<span class="sourceLineNo">238</span>  private void updateLastFlushedSequenceIds(ServerName sn, ServerMetrics hsl) {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    for (Entry&lt;byte[], RegionMetrics&gt; entry : hsl.getRegionMetrics().entrySet()) {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey()));<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      long l = entry.getValue().getCompletedSequenceId();<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      // Don't let smaller sequence ids override greater sequence ids.<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      if (LOG.isTraceEnabled()) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>        LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue<a name="line.245"></a>
-<span class="sourceLineNo">246</span>          + ", completeSequenceId=" + l);<a name="line.246"></a>
-<span class="sourceLineNo">247</span>      }<a name="line.247"></a>
-<span class="sourceLineNo">248</span>      if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue)) {<a name="line.248"></a>
-<span class="sourceLineNo">249</span>        flushedSequenceIdByRegion.put(encodedRegionName, l);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>      } else if (l != HConstants.NO_SEQNUM &amp;&amp; l &lt; existingValue) {<a name="line.250"></a>
-<span class="sourceLineNo">251</span>        LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l<a name="line.251"></a>
-<span class="sourceLineNo">252</span>          + ") that is less than the previous last flushed sequence id (" + existingValue<a name="line.252"></a>
-<span class="sourceLineNo">253</span>          + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring.");<a name="line.253"></a>
-<span class="sourceLineNo">254</span>      }<a name="line.254"></a>
-<span class="sourceLineNo">255</span>      ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.256"></a>
-<span class="sourceLineNo">257</span>          () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      for (Entry&lt;byte[], Long&gt; storeSeqId : entry.getValue().getStoreSequenceId().entrySet()) {<a name="line.258"></a>
-<span class="sourceLineNo">259</span>        byte[] family = storeSeqId.getKey();<a name="line.259"></a>
-<span class="sourceLineNo">260</span>        existingValue = storeFlushedSequenceId.get(family);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>        l = storeSeqId.getValue();<a name="line.261"></a>
-<span class="sourceLineNo">262</span>        if (LOG.isTraceEnabled()) {<a name="line.262"></a>
-<span class="sourceLineNo">263</span>          LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family)<a name="line.263"></a>
-<span class="sourceLineNo">264</span>            + ", existingValue=" + existingValue + ", completeSequenceId=" + l);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>        }<a name="line.265"></a>
-<span class="sourceLineNo">266</span>        // Don't let smaller sequence ids override greater sequence ids.<a name="line.266"></a>
-<span class="sourceLineNo">267</span>        if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue.longValue())) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>          storeFlushedSequenceId.put(family, l);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        }<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    }<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>  public void regionServerReport(ServerName sn, ServerMetrics sl) throws YouAreDeadException {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>    checkIsDead(sn, "REPORT");<a name="line.275"></a>
-<span class="sourceLineNo">276</span>    if (null == this.onlineServers.replace(sn, sl)) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      // Already have this host+port combo and its just different start code?<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      // Just let the server in. Presume master joining a running cluster.<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      // recordNewServer is what happens at the end of reportServerStartup.<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      // The only thing we are skipping is passing back to the regionserver<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      // the ServerName to use. Here we presume a master has already done<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      // that so we'll press on with whatever it gave us for ServerName.<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      if (!checkAndRecordNewServer(sn, sl)) {<a name="line.283"></a>
-<span class="sourceLineNo">284</span>        LOG.info("RegionServerReport ignored, could not record the server: " + sn);<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        return; // Not recorded, so no need to move on<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      }<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    updateLastFlushedSequenceIds(sn, sl);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
-<span class="sourceLineNo">290</span><a name="line.290"></a>
-<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Check is a server of same host and port already exists, if not, or the existed one got a<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * smaller start code, record it.<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   * @param serverName the server to check and record<a name="line.294"></a>
-<span class="sourceLineNo">295</span>   * @param sl         the server load on the server<a name="line.295"></a>
-<span class="sourceLineNo">296</span>   * @return true if the server is recorded, otherwise, false<a name="line.296"></a>
-<span class="sourceLineNo">297</span>   */<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  boolean checkAndRecordNewServer(final ServerName serverName, final ServerMetrics sl) {<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    ServerName existingServer = null;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>    synchronized (this.onlineServers) {<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      existingServer = findServerWithSameHostnamePortWithLock(serverName);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      if (existingServer != null &amp;&amp; (existingServer.getStartcode() &gt; serverName.getStartcode())) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>        LOG.info("Server serverName=" + serverName + " rejected; we already have "<a name="line.303"></a>
-<span class="sourceLineNo">304</span>          + existingServer.toString() + " registered with same hostname and port");<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        return false;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>      recordNewServerWithLock(serverName, sl);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
-<span class="sourceLineNo">309</span><a name="line.309"></a>
-<span class="sourceLineNo">310</span>    // Tell our listeners that a server was added<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    if (!this.listeners.isEmpty()) {<a name="line.311"></a>
-<span class="sourceLineNo">312</span>      for (ServerListener listener : this.listeners) {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>        listener.serverAdded(serverName);<a name="line.313"></a>
-<span class="sourceLineNo">314</span>      }<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    }<a name="line.315"></a>
-<span class="sourceLineNo">316</span><a name="line.316"></a>
-<span class="sourceLineNo">317</span>    // Note that we assume that same ts means same server, and don't expire in that case.<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    // TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    if (existingServer != null &amp;&amp; (existingServer.getStartcode() &lt; serverName.getStartcode())) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      LOG.info("Triggering server recovery; existingServer " + existingServer<a name="line.320"></a>
-<span class="sourceLineNo">321</span>        + " looks stale, new server:" + serverName);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      expireServer(existingServer);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    return true;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>  }<a name="line.325"></a>
-<span class="sourceLineNo">326</span><a name="line.326"></a>
-<span class="sourceLineNo">327</span>  /**<a name="line.327"></a>
-<span class="sourceLineNo">328</span>   * Find out the region servers crashed between the crash of the previous master instance and the<a name="line.328"></a>
-<span class="sourceLineNo">329</span>   * current master instance and schedule SCP for them.<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * &lt;p/&gt;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * Since the {@code RegionServerTracker} has already helped us to construct the online servers set<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   * by scanning zookeeper, now we can compare the online servers with {@code liveServersFromWALDir}<a name="line.332"></a>
-<span class="sourceLineNo">333</span>   * to find out whether there are servers which are already dead.<a name="line.333"></a>
-<span class="sourceLineNo">334</span>   * &lt;p/&gt;<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * Must be called inside the initialization method of {@code RegionServerTracker} to avoid<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * concurrency issue.<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   * @param deadServersFromPE     the region servers which already have a SCP associated.<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param liveServersFromWALDir the live region servers from wal directory.<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   */<a name="line.339"></a>
-<span class="sourceLineNo">340</span>  void findDeadServersAndProcess(Set&lt;ServerName&gt; deadServersFromPE,<a name="line.340"></a>
-<span class="sourceLineNo">341</span>    Set&lt;ServerName&gt; liveServersFromWALDir) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    deadServersFromPE.forEach(deadservers::putIfAbsent);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    liveServersFromWALDir.stream().filter(sn -&gt; !onlineServers.containsKey(sn))<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      .forEach(this::expireServer);<a name="line.344"></a>
-<span class="sourceLineNo">345</span>  }<a name="line.345"></a>
-<span class="sourceLineNo">346</span><a name="line.346"></a>
-<span class="sourceLineNo">347</span>  /**<a name="line.347"></a>
-<span class="sourceLineNo">348</span>   * Checks if the clock skew between the server and the master. If the clock skew exceeds the<a name="line.348"></a>
-<span class="sourceLineNo">349</span>   * configured max, it will throw an exception; if it exceeds the configured warning threshold, it<a name="line.349"></a>
-<span class="sourceLineNo">350</span>   * will log a warning but start normally.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>   * @param serverName Incoming servers's name n * @throws ClockOutOfSyncException if the skew<a name="line.351"></a>
-<span class="sourceLineNo">352</span>   *                   exceeds the configured max value<a name="line.352"></a>
-<span class="sourceLineNo">353</span>   */<a name="line.353"></a>
-<span class="sourceLineNo">354</span>  private void checkClockSkew(final ServerName serverName, final long serverCurrentTime)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>    throws ClockOutOfSyncException {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    long skew = Math.abs(EnvironmentEdgeManager.currentTime() - serverCurrentTime);<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    if (skew &gt; maxSkew) {<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      String message = "Server " + serverName + " has been "<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        + "rejected; Reported time is too far out of sync with master.  " + "Time difference of "<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        + skew + "ms &gt; max allowed of " + maxSkew + "ms";<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      LOG.warn(message);<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      throw new ClockOutOfSyncException(message);<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    } else if (skew &gt; warningSkew) {<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      String message = "Reported time for server " + serverName + " is out of sync with master "<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        + "by " + skew + "ms. (Warning threshold is " + warningSkew + "ms; " + "error threshold is "<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        + maxSkew + "ms)";<a name="line.366"></a>
-<span class="sourceLineNo">367</span>      LOG.warn(message);<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  }<a name="line.369"></a>
-<span class="sourceLineNo">370</span><a name="line.370"></a>
-<span class="sourceLineNo">371</span>  /**<a name="line.371"></a>
-<span class="sourceLineNo">372</span>   * Called when RegionServer first reports in for duty and thereafter each time it heartbeats to<a name="line.372"></a>
-<span class="sourceLineNo">373</span>   * make sure it is has not been figured for dead. If this server is on the dead list, reject it<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * with a YouAreDeadException. If it was dead but came back with a new start code, remove the old<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * entry from the dead list.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   * @param what START or REPORT<a name="line.376"></a>
-<span class="sourceLineNo">377</span>   */<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  private void checkIsDead(final ServerName serverName, final String what)<a name="line.378"></a>
-<span class="sourceLineNo">379</span>    throws YouAreDeadException {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>      // Exact match: host name, port and start code all match with existing one of the<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      // dead servers. So, this server must be dead. Tell it to kill itself.<a name="line.382"></a>
-<span class="sourceLineNo">383</span>      String message =<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        "Server " + what + " rejected; currently processing " + serverName + " as dead server";<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      LOG.debug(message);<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      throw new YouAreDeadException(message);<a name="line.386"></a>
-<span class="sourceLineNo">387</span>    }<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    // Remove dead server with same hostname and port of newly checking in rs after master<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    // initialization. See HBASE-5916 for more information.<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    if (<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      (this.master == null || this.master.isInitialized())<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        &amp;&amp; this.deadservers.cleanPreviousInstance(serverName)<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    ) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      // This server has now become alive after we marked it as dead.<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      // We removed it's previous entry from the dead list to reflect it.<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      LOG.debug("{} {} came back up, removed it from the dead servers list", what, serverName);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>  }<a name="line.398"></a>
-<span class="sourceLineNo">399</span><a name="line.399"></a>
-<span class="sourceLineNo">400</span>  /**<a name="line.400"></a>
-<span class="sourceLineNo">401</span>   * Assumes onlineServers is locked.<a name="line.401"></a>
-<span class="sourceLineNo">402</span>   * @return ServerName with matching hostname and port.<a name="line.402"></a>
-<span class="sourceLineNo">403</span>   */<a name="line.403"></a>
-<span class="sourceLineNo">404</span>  private ServerName findServerWithSameHostnamePortWithLock(final ServerName serverName) {<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    ServerName end =<a name="line.405"></a>
-<span class="sourceLineNo">406</span>      ServerName.valueOf(serverName.getHostname(), serverName.getPort(), Long.MAX_VALUE);<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    ServerName r = onlineServers.lowerKey(end);<a name="line.408"></a>
-<span class="sourceLineNo">409</span>    if (r != null) {<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      if (ServerName.isSameAddress(r, serverName)) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>        return r;<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      }<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    }<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    return null;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>  }<a name="line.415"></a>
-<span class="sourceLineNo">416</span><a name="line.416"></a>
-<span class="sourceLineNo">417</span>  /**<a name="line.417"></a>
-<span class="sourceLineNo">418</span>   * Adds the onlineServers list. onlineServers should be locked.<a name="line.418"></a>
-<span class="sourceLineNo">419</span>   * @param serverName The remote servers name.<a name="line.419"></a>
-<span class="sourceLineNo">420</span>   */<a name="line.420"></a>
-<span class="sourceLineNo">421</span>  void recordNewServerWithLock(final ServerName serverName, final ServerMetrics sl) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    LOG.info("Registering regionserver=" + serverName);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>    this.onlineServers.put(serverName, sl);<a name="line.423"></a>
-<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
-<span class="sourceLineNo">425</span><a name="line.425"></a>
-<span class="sourceLineNo">426</span>  public ConcurrentNavigableMap&lt;byte[], Long&gt; getFlushedSequenceIdByRegion() {<a name="line.426"></a>
-<span class="sourceLineNo">427</span>    return flushedSequenceIdByRegion;<a name="line.427"></a>
-<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
-<span class="sourceLineNo">429</span><a name="line.429"></a>
-<span class="sourceLineNo">430</span>  public RegionStoreSequenceIds getLastFlushedSequenceId(byte[] encodedRegionName) {<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    RegionStoreSequenceIds.Builder builder = RegionStoreSequenceIds.newBuilder();<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    Long seqId = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    builder.setLastFlushedSequenceId(seqId != null ? seqId.longValue() : HConstants.NO_SEQNUM);<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    Map&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      storeFlushedSequenceIdsByRegion.get(encodedRegionName);<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    if (storeFlushedSequenceId != null) {<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      for (Map.Entry&lt;byte[], Long&gt; entry : storeFlushedSequenceId.entrySet()) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>        builder.addStoreSequenceId(StoreSequenceId.newBuilder()<a name="line.438"></a>
-<span class="sourceLineNo">439</span>          .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey()))<a name="line.439"></a>
-<span class="sourceLineNo">440</span>          .setSequenceId(entry.getValue().longValue()).build());<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      }<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    }<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    return builder.build();<a name="line.443"></a>
-<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>  /**<a name="line.446"></a>
-<span class="sourceLineNo">447</span>   * n * @return ServerMetrics if serverName is known else null<a name="line.447"></a>
-<span class="sourceLineNo">448</span>   */<a name="line.448"></a>
-<span class="sourceLineNo">449</span>  public ServerMetrics getLoad(final ServerName serverName) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    return this.onlineServers.get(serverName);<a name="line.450"></a>
-<span class="sourceLineNo">451</span>  }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>  /**<a name="line.453"></a>
-<span class="sourceLineNo">454</span>   * Compute the average load across all region servers. Currently, this uses a very naive<a name="line.454"></a>
-<span class="sourceLineNo">455</span>   * computation - just uses the number of regions being served, ignoring stats about number of<a name="line.455"></a>
-<span class="sourceLineNo">456</span>   * requests.<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * @return the average load<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   */<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  public double getAverageLoad() {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    int totalLoad = 0;<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    int numServers = 0;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    for (ServerMetrics sl : this.onlineServers.values()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>      numServers++;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>      totalLoad += sl.getRegionMetrics().size();<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    return numServers == 0 ? 0 : (double) totalLoad / (double) numServers;<a name="line.466"></a>
-<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
-<span class="sourceLineNo">468</span><a name="line.468"></a>
-<span class="sourceLineNo">469</span>  /** Returns the count of active regionservers */<a name="line.469"></a>
-<span class="sourceLineNo">470</span>  public int countOfRegionServers() {<a name="line.470"></a>
-<span class="sourceLineNo">471</span>    // Presumes onlineServers is a concurrent map<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    return this.onlineServers.size();<a name="line.472"></a>
-<span class="sourceLineNo">473</span>  }<a name="line.473"></a>
-<span class="sourceLineNo">474</span><a name="line.474"></a>
-<span class="sourceLineNo">475</span>  /** Returns Read-only map of servers to serverinfo */<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  public Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    // Presumption is that iterating the returned Map is OK.<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    synchronized (this.onlineServers) {<a name="line.478"></a>
-<span class="sourceLineNo">479</span>      return Collections.unmodifiableMap(this.onlineServers);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
-<span class="sourceLineNo">482</span><a name="line.482"></a>
-<span class="sourceLineNo">483</span>  public DeadServer getDeadServers() {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return this.deadservers;<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  /**<a name="line.487"></a>
-<span class="sourceLineNo">488</span>   * Checks if any dead servers are currently in progress.<a name="line.488"></a>
-<span class="sourceLineNo">489</span>   * @return true if any RS are being processed as dead, false if not<a name="line.489"></a>
-<span class="sourceLineNo">490</span>   */<a name="line.490"></a>
-<span class="sourceLineNo">491</span>  public boolean areDeadServersInProgress() throws IOException {<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return master.getProcedures().stream()<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      .anyMatch(p -&gt; !p.isFinished() &amp;&amp; p instanceof ServerCrashProcedure);<a name="line.493"></a>
-<span class="sourceLineNo">494</span>  }<a name="line.494"></a>
-<span class="sourceLineNo">495</span><a name="line.495"></a>
-<span class="sourceLineNo">496</span>  void letRegionServersShutdown() {<a name="line.496"></a>
-<span class="sourceLineNo">497</span>    long previousLogTime = 0;<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    ServerName sn = master.getServerName();<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    ZKWatcher zkw = master.getZooKeeper();<a name="line.499"></a>
-<span class="sourceLineNo">500</span>    int onlineServersCt;<a name="line.500"></a>
-<span class="sourceLineNo">501</span>    while ((onlineServersCt = onlineServers.size()) &gt; 0) {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        Set&lt;ServerName&gt; remainingServers = onlineServers.keySet();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        synchronized (onlineServers) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          if (remainingServers.size() == 1 &amp;&amp; remainingServers.contains(sn)) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>            // Master will delete itself later.<a name="line.506"></a>
-<span class="sourceLineNo">507</span>            return;<a name="line.507"></a>
-<span class="sourceLineNo">508</span>          }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>        }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        StringBuilder sb = new StringBuilder();<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        // It's ok here to not sync on onlineServers - merely logging<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        for (ServerName key : remainingServers) {<a name="line.512"></a>
-<span class="sourceLineNo">513</span>          if (sb.length() &gt; 0) {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>            sb.append(", ");<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          }<a name="line.515"></a>
-<span class="sourceLineNo">516</span>          sb.append(key);<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        LOG.info("Waiting on regionserver(s) " + sb.toString());<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        previousLogTime = EnvironmentEdgeManager.currentTime();<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span><a name="line.521"></a>
-<span class="sourceLineNo">522</span>      try {<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        List&lt;String&gt; servers = getRegionServersInZK(zkw);<a name="line.523"></a>
-<span class="sourceLineNo">524</span>        if (<a name="line.524"></a>
-<span class="sourceLineNo">525</span>          servers == null || servers.isEmpty()<a name="line.525"></a>
-<span class="sourceLineNo">526</span>            || (servers.size() == 1 &amp;&amp; servers.contains(sn.toString()))<a name="line.526"></a>
-<span class="sourceLineNo">527</span>        ) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          LOG.info("ZK shows there is only the master self online, exiting now");<a name="line.528"></a>
-<span class="sourceLineNo">529</span>          // Master could have lost some ZK events, no need to wait more.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          break;<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      } catch (KeeperException ke) {<a name="line.532"></a>
-<span class="sourceLineNo">533</span>        LOG.warn("Failed to list regionservers", ke);<a name="line.533"></a>
-<span class="sourceLineNo">534</span>        // ZK is malfunctioning, don't hang here<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        break;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      }<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      synchronized (onlineServers) {<a name="line.537"></a>
-<span class="sourceLineNo">538</span>        try {<a name="line.538"></a>
-<span class="sourceLineNo">539</span>          if (onlineServersCt == onlineServers.size()) onlineServers.wait(100);<a name="line.539"></a>
-<span class="sourceLineNo">540</span>        } catch (InterruptedException ignored) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>          // continue<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        }<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
-<span class="sourceLineNo">545</span>  }<a name="line.545"></a>
-<span class="sourceLineNo">546</span><a name="line.546"></a>
-<span class="sourceLineNo">547</span>  private List&lt;String&gt; getRegionServersInZK(final ZKWatcher zkw) throws KeeperException {<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    return ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>  /**<a name="line.551"></a>
-<span class="sourceLineNo">552</span>   * Expire the passed server. Add it to list of dead servers and queue a shutdown processing.<a name="line.552"></a>
-<span class="sourceLineNo">553</span>   * @return pid if we queued a ServerCrashProcedure else {@link Procedure#NO_PROC_ID} if we did not<a name="line.553"></a>
-<span class="sourceLineNo">554</span>   *         (could happen for many reasons including the fact that its this server that is going<a name="line.554"></a>
-<span class="sourceLineNo">555</span>   *         down or we already have queued an SCP for this server or SCP processing is currently<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   *         disabled because we are in startup phase).<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   */<a name="line.557"></a>
-<span class="sourceLineNo">558</span>  // Redo test so we can make this protected.<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  public synchronized long expireServer(final ServerName serverName) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return expireServer(serverName, false);<a name="line.560"></a>
-<span class="sourceLineNo">561</span><a name="line.561"></a>
-<span class="sourceLineNo">562</span>  }<a name="line.562"></a>
-<span class="sourceLineNo">563</span><a name="line.563"></a>
-<span class="sourceLineNo">564</span>  synchronized long expireServer(final ServerName serverName, boolean force) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    // THIS server is going down... can't handle our own expiration.<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    if (serverName.equals(master.getServerName())) {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>      if (!(master.isAborted() || master.isStopped())) {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>        master.stop("We lost our znode?");<a name="line.568"></a>
-<span class="sourceLineNo">569</span>      }<a name="line.569"></a>
-<span class="sourceLineNo">570</span>      return Procedure.NO_PROC_ID;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>    }<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.572"></a>
-<span class="sourceLineNo">573</span>      LOG.warn("Expiration called on {} but already in DeadServer", serverName);<a name="line.573"></a>
-<span class="sourceLineNo">574</span>      return Procedure.NO_PROC_ID;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    moveFromOnlineToDeadServers(serverName);<a name="line.576"></a>
-<span class="sourceLineNo">577</span><a name="line.577"></a>
-<span class="sourceLineNo">578</span>    // If server is in draining mode, remove corresponding znode<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    // In some tests, the mocked HM may not have ZK Instance, hence null check<a name="line.579"></a>
-<span class="sourceLineNo">580</span>    if (master.getZooKeeper() != null) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>      String drainingZnode = ZNodePaths<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        .joinZNode(master.getZooKeeper().getZNodePaths().drainingZNode, serverName.getServerName());<a name="line.582"></a>
-<span class="sourceLineNo">583</span>      try {<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        ZKUtil.deleteNodeFailSilent(master.getZooKeeper(), drainingZnode);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>      } catch (KeeperException e) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        LOG.warn(<a name="line.586"></a>
-<span class="sourceLineNo">587</span>          "Error deleting the draining znode for stopping server " + serverName.getServerName(), e);<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      }<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    }<a name="line.589"></a>
-<span class="sourceLineNo">590</span><a name="line.590"></a>
-<span class="sourceLineNo">591</span>    // If cluster is going down, yes, servers are going to be expiring; don't<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    // process as a dead server<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (isClusterShutdown()) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      LOG.info("Cluster shutdown set; " + serverName + " expired; onlineServers="<a name="line.594"></a>
-<span class="sourceLineNo">595</span>        + this.onlineServers.size());<a name="line.595"></a>
-<span class="sourceLineNo">596</span>      if (this.onlineServers.isEmpty()) {<a name="line.596"></a>
-<span class="sourceLineNo">597</span>        master.stop("Cluster shutdown set; onlineServer=0");<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      }<a name="line.598"></a>
-<span class="sourceLineNo">599</span>      return Procedure.NO_PROC_ID;<a name="line.599"></a>
-<span class="sourceLineNo">600</span>    }<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    LOG.info("Processing expiration of " + serverName + " on " + this.master.getServerName());<a name="line.601"></a>
-<span class="sourceLineNo">602</span>    long pid = master.getAssignmentManager().submitServerCrash(serverName, true, force);<a name="line.602"></a>
-<span class="sourceLineNo">603</span>    storage.expired(serverName);<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    // Tell our listeners that a server was removed<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    if (!this.listeners.isEmpty()) {<a name="line.605"></a>
-<span class="sourceLineNo">606</span>      this.listeners.stream().forEach(l -&gt; l.serverRemoved(serverName));<a name="line.606"></a>
-<span class="sourceLineNo">607</span>    }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    // trigger a persist of flushedSeqId<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    if (flushedSeqIdFlusher != null) {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>      flushedSeqIdFlusher.triggerNow();<a name="line.610"></a>
-<span class="sourceLineNo">611</span>    }<a name="line.611"></a>
-<span class="sourceLineNo">612</span>    return pid;<a name="line.612"></a>
-<span class="sourceLineNo">613</span>  }<a name="line.613"></a>
-<span class="sourceLineNo">614</span><a name="line.614"></a>
-<span class="sourceLineNo">615</span>  /**<a name="line.615"></a>
-<span class="sourceLineNo">616</span>   * Called when server has expired.<a name="line.616"></a>
-<span class="sourceLineNo">617</span>   */<a name="line.617"></a>
-<span class="sourceLineNo">618</span>  // Locking in this class needs cleanup.<a name="line.618"></a>
-<span class="sourceLineNo">619</span>  public synchronized void moveFromOnlineToDeadServers(final ServerName sn) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    synchronized (this.onlineServers) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      boolean online = this.onlineServers.containsKey(sn);<a name="line.621"></a>
-<span class="sourceLineNo">622</span>      if (online) {<a name="line.622"></a>
-<span class="sourceLineNo">623</span>        // Remove the server from the known servers lists and update load info BUT<a name="line.623"></a>
-<span class="sourceLineNo">624</span>        // add to deadservers first; do this so it'll show in dead servers list if<a name="line.624"></a>
-<span class="sourceLineNo">625</span>        // not in online servers list.<a name="line.625"></a>
-<span class="sourceLineNo">626</span>        this.deadservers.putIfAbsent(sn);<a name="line.626"></a>
-<span class="sourceLineNo">627</span>        this.onlineServers.remove(sn);<a name="line.627"></a>
-<span class="sourceLineNo">628</span>        onlineServers.notifyAll();<a name="line.628"></a>
-<span class="sourceLineNo">629</span>      } else {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>        // If not online, that is odd but may happen if 'Unknown Servers' -- where meta<a name="line.630"></a>
-<span class="sourceLineNo">631</span>        // has references to servers not online nor in dead servers list. If<a name="line.631"></a>
-<span class="sourceLineNo">632</span>        // 'Unknown Server', don't add to DeadServers else will be there for ever.<a name="line.632"></a>
-<span class="sourceLineNo">633</span>        LOG.trace("Expiration of {} but server not online", sn);<a name="line.633"></a>
-<span class="sourceLineNo">634</span>      }<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    }<a name="line.635"></a>
-<span class="sourceLineNo">636</span>  }<a name="line.636"></a>
-<span class="sourceLineNo">637</span><a name="line.637"></a>
-<span class="sourceLineNo">638</span>  /*<a name="line.638"></a>
-<span class="sourceLineNo">639</span>   * Remove the server from the drain list.<a name="line.639"></a>
-<span class="sourceLineNo">640</span>   */<a name="line.640"></a>
-<span class="sourceLineNo">641</span>  public synchronized boolean removeServerFromDrainList(final ServerName sn) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.642"></a>
-<span class="sourceLineNo">643</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.643"></a>
-<span class="sourceLineNo">644</span><a name="line.644"></a>
-<span class="sourceLineNo">645</span>    if (!this.isServerOnline(sn)) {<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.646"></a>
-<span class="sourceLineNo">647</span>        + "Removing from draining list anyway, as requested.");<a name="line.647"></a>
-<span class="sourceLineNo">648</span>    }<a name="line.648"></a>
-<span class="sourceLineNo">649</span>    // Remove the server from the draining servers lists.<a name="line.649"></a>
-<span class="sourceLineNo">650</span>    return this.drainingServers.remove(sn);<a name="line.650"></a>
-<span class="sourceLineNo">651</span>  }<a name="line.651"></a>
-<span class="sourceLineNo">652</span><a name="line.652"></a>
-<span class="sourceLineNo">653</span>  /**<a name="line.653"></a>
-<span class="sourceLineNo">654</span>   * Add the server to the drain list. n * @return True if the server is added or the server is<a name="line.654"></a>
-<span class="sourceLineNo">655</span>   * already on the drain list.<a name="line.655"></a>
-<span class="sourceLineNo">656</span>   */<a name="line.656"></a>
-<span class="sourceLineNo">657</span>  public synchronized boolean addServerToDrainList(final ServerName sn) {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.659"></a>
-<span class="sourceLineNo">660</span><a name="line.660"></a>
-<span class="sourceLineNo">661</span>    if (!this.isServerOnline(sn)) {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.662"></a>
-<span class="sourceLineNo">663</span>        + "Ignoring request to add it to draining list.");<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      return false;<a name="line.664"></a>
-<span class="sourceLineNo">665</span>    }<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    // Add the server to the draining servers lists, if it's not already in<a name="line.666"></a>
-<span class="sourceLineNo">667</span>    // it.<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    if (this.drainingServers.contains(sn)) {<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      LOG.warn("Server " + sn + " is already in the draining server list."<a name="line.669"></a>
-<span class="sourceLineNo">670</span>        + "Ignoring request to add it again.");<a name="line.670"></a>
-<span class="sourceLineNo">671</span>      return true;<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    }<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    LOG.info("Server " + sn + " added to draining server list.");<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    return this.drainingServers.add(sn);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>  }<a name="line.675"></a>
-<span class="sourceLineNo">676</span><a name="line.676"></a>
-<span class="sourceLineNo">677</span>  /**<a name="line.677"></a>
-<span class="sourceLineNo">678</span>   * Contacts a region server and waits up to timeout ms to close the region. This bypasses the<a name="line.678"></a>
-<span class="sourceLineNo">679</span>   * active hmaster. Pass -1 as timeout if you do not want to wait on result.<a name="line.679"></a>
-<span class="sourceLineNo">680</span>   */<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  public static void closeRegionSilentlyAndWait(AsyncClusterConnection connection,<a name="line.681"></a>
-<span class="sourceLineNo">682</span>    ServerName server, RegionInfo region, long timeout) throws IOException, InterruptedException {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    AsyncRegionServerAdmin admin = connection.getRegionServerAdmin(server);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>    try {<a name="line.684"></a>
-<span class="sourceLineNo">685</span>      FutureUtils.get(<a name="line.685"></a>
-<span class="sourceLineNo">686</span>        admin.closeRegion(ProtobufUtil.buildCloseRegionRequest(server, region.getRegionName())));<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    } catch (IOException e) {<a name="line.687"></a>
-<span class="sourceLineNo">688</span>      LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    }<a name="line.689"></a>
-<span class="sourceLineNo">690</span>    if (timeout &lt; 0) {<a name="line.690"></a>
-<span class="sourceLineNo">691</span>      return;<a name="line.691"></a>
-<span class="sourceLineNo">692</span>    }<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    long expiration = timeout + EnvironmentEdgeManager.currentTime();<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    while (EnvironmentEdgeManager.currentTime() &lt; expiration) {<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      try {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>        RegionInfo rsRegion = ProtobufUtil.toRegionInfo(FutureUtils<a name="line.696"></a>
-<span class="sourceLineNo">697</span>          .get(<a name="line.697"></a>
-<span class="sourceLineNo">698</span>            admin.getRegionInfo(RequestConverter.buildGetRegionInfoRequest(region.getRegionName())))<a name="line.698"></a>
-<span class="sourceLineNo">699</span>          .getRegionInfo());<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        if (rsRegion == null) {<a name="line.700"></a>
-<span class="sourceLineNo">701</span>          return;<a name="line.701"></a>
-<span class="sourceLineNo">702</span>        }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      } catch (IOException ioe) {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>        if (<a name="line.704"></a>
-<span class="sourceLineNo">705</span>          ioe instanceof NotServingRegionException<a name="line.705"></a>
-<span class="sourceLineNo">706</span>            || (ioe instanceof RemoteWithExtrasException &amp;&amp; ((RemoteWithExtrasException) ioe)<a name="line.706"></a>
-<span class="sourceLineNo">707</span>              .unwrapRemoteException() instanceof NotServingRegionException)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>        ) {<a name="line.708"></a>
-<span class="sourceLineNo">709</span>          // no need to retry again<a name="line.709"></a>
-<span class="sourceLineNo">710</span>          return;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>        }<a name="line.711"></a>
-<span class="sourceLineNo">712</span>        LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(),<a name="line.712"></a>
-<span class="sourceLineNo">713</span>          ioe);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      }<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      Thread.sleep(1000);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    }<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>  }<a name="line.718"></a>
-<span class="sourceLineNo">719</span><a name="line.719"></a>
-<span class="sourceLineNo">720</span>  /**<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   * Calculate min necessary to start. This is not an absolute. It is just a friction that will<a name="line.721"></a>
-<span class="sourceLineNo">722</span>   * cause us hang around a bit longer waiting on RegionServers to check-in.<a name="line.722"></a>
-<span class="sourceLineNo">723</span>   */<a name="line.723"></a>
-<span class="sourceLineNo">724</span>  private int getMinToStart() {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    if (master.isInMaintenanceMode()) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      // If in maintenance mode, then in process region server hosting meta will be the only server<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      // available<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      return 1;<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    }<a name="line.729"></a>
-<span class="sourceLineNo">730</span><a name="line.730"></a>
-<span class="sourceLineNo">731</span>    int minimumRequired = 1;<a name="line.731"></a>
-<span class="sourceLineNo">732</span>    int minToStart = this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MINTOSTART, -1);<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    // Ensure we are never less than minimumRequired else stuff won't work.<a name="line.733"></a>
-<span class="sourceLineNo">734</span>    return Math.max(minToStart, minimumRequired);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  }<a name="line.735"></a>
-<span class="sourceLineNo">736</span><a name="line.736"></a>
-<span class="sourceLineNo">737</span>  /**<a name="line.737"></a>
-<span class="sourceLineNo">738</span>   * Wait for the region servers to report in. We will wait until one of this condition is met: -<a name="line.738"></a>
-<span class="sourceLineNo">739</span>   * the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region<a name="line.739"></a>
-<span class="sourceLineNo">740</span>   * servers is reached - the 'hbase.master.wait.on.regionservers.mintostart' is reached AND there<a name="line.740"></a>
-<span class="sourceLineNo">741</span>   * have been no new region server in for 'hbase.master.wait.on.regionservers.interval' time AND<a name="line.741"></a>
-<span class="sourceLineNo">742</span>   * the 'hbase.master.wait.on.regionservers.timeout' is reached n<a name="line.742"></a>
-<span class="sourceLineNo">743</span>   */<a name="line.743"></a>
-<span class="sourceLineNo">744</span>  public void waitForRegionServers(MonitoredTask status) throws InterruptedException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    final long interval =<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_INTERVAL, 1500);<a name="line.746"></a>
-<span class="sourceLineNo">747</span>    final long timeout =<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_TIMEOUT, 4500);<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    // Min is not an absolute; just a friction making us wait longer on server checkin.<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    int minToStart = getMinToStart();<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    int maxToStart =<a name="line.751"></a>
-<span class="sourceLineNo">752</span>      this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MAXTOSTART, Integer.MAX_VALUE);<a name="line.752"></a>
-<span class="sourceLineNo">753</span>    if (maxToStart &lt; minToStart) {<a name="line.753"></a>
-<span class="sourceLineNo">754</span>      LOG.warn(String.format("The value of '%s' (%d) is set less than '%s' (%d), ignoring.",<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        WAIT_ON_REGIONSERVERS_MAXTOSTART, maxToStart, WAIT_ON_REGIONSERVERS_MINTOSTART,<a name="line.755"></a>
-<span class="sourceLineNo">756</span>        minToStart));<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      maxToStart = Integer.MAX_VALUE;<a name="line.757"></a>
-<span class="sourceLineNo">758</span>    }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>    long now = EnvironmentEdgeManager.currentTime();<a name="line.760"></a>
-<span class="sourceLineNo">761</span>    final long startTime = now;<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    long slept = 0;<a name="line.762"></a>
-<span class="sourceLineNo">763</span>    long lastLogTime = 0;<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    long lastCountChange = startTime;<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    int count = countOfRegionServers();<a name="line.765"></a>
-<span class="sourceLineNo">766</span>    int oldCount = 0;<a name="line.766"></a>
-<span class="sourceLineNo">767</span>    // This while test is a little hard to read. We try to comment it in below but in essence:<a name="line.767"></a>
-<span class="sourceLineNo">768</span>    // Wait if Master is not stopped and the number of regionservers that have checked-in is<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    // less than the maxToStart. Both of these conditions will be true near universally.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>    // Next, we will keep cycling if ANY of the following three conditions are true:<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    // 1. The time since a regionserver registered is &lt; interval (means servers are actively<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    // checking in).<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    // 2. We are under the total timeout.<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    // 3. The count of servers is &lt; minimum.<a name="line.774"></a>
-<span class="sourceLineNo">775</span>    for (ServerListener listener : this.listeners) {<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      listener.waiting();<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    while (<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      !this.master.isStopped() &amp;&amp; !isClusterShutdown() &amp;&amp; count &lt; maxToStart<a name="line.779"></a>
-<span class="sourceLineNo">780</span>        &amp;&amp; ((lastCountChange + interval) &gt; now || timeout &gt; slept || count &lt; minToStart)<a name="line.780"></a>
-<span class="sourceLineNo">781</span>    ) {<a name="line.781"></a>
-<span class="sourceLineNo">782</span>      // Log some info at every interval time or if there is a change<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      if (oldCount != count || lastLogTime + interval &lt; now) {<a name="line.783"></a>
-<span class="sourceLineNo">784</span>        lastLogTime = now;<a name="line.784"></a>
-<span class="sourceLineNo">785</span>        String msg =<a name="line.785"></a>
-<span class="sourceLineNo">786</span>          "Waiting on regionserver count=" + count + "; waited=" + slept + "ms, expecting min="<a name="line.786"></a>
-<span class="sourceLineNo">787</span>            + minToStart + " server(s), max=" + getStrForMax(maxToStart) + " server(s), "<a name="line.787"></a>
-<span class="sourceLineNo">788</span>            + "timeout=" + timeout + "ms, lastChange=" + (now - lastCountChange) + "ms";<a name="line.788"></a>
-<span class="sourceLineNo">789</span>        LOG.info(msg);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        status.setStatus(msg);<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span><a name="line.792"></a>
-<span class="sourceLineNo">793</span>      // We sleep for some time<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      final long sleepTime = 50;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>      Thread.sleep(sleepTime);<a name="line.795"></a>
-<span class="sourceLineNo">796</span>      now = EnvironmentEdgeManager.currentTime();<a name="line.796"></a>
-<span class="sourceLineNo">797</span>      slept = now - startTime;<a name="line.797"></a>
-<span class="sourceLineNo">798</span><a name="line.798"></a>
-<span class="sourceLineNo">799</span>      oldCount = count;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>      count = countOfRegionServers();<a name="line.800"></a>
-<span class="sourceLineNo">801</span>      if (count != oldCount) {<a name="line.801"></a>
-<span class="sourceLineNo">802</span>        lastCountChange = now;<a name="line.802"></a>
-<span class="sourceLineNo">803</span>      }<a name="line.803"></a>
-<span class="sourceLineNo">804</span>    }<a name="line.804"></a>
-<span class="sourceLineNo">805</span>    // Did we exit the loop because cluster is going down?<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    if (isClusterShutdown()) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>      this.master.stop("Cluster shutdown");<a name="line.807"></a>
-<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
-<span class="sourceLineNo">809</span>    LOG.info("Finished waiting on RegionServer count=" + count + "; waited=" + slept + "ms,"<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      + " expected min=" + minToStart + " server(s), max=" + getStrForMax(maxToStart)<a name="line.810"></a>
-<span class="sourceLineNo">811</span>      + " server(s)," + " master is " + (this.master.isStopped() ? "stopped." : "running"));<a name="line.811"></a>
-<span class="sourceLineNo">812</span>  }<a name="line.812"></a>
-<span class="sourceLineNo">813</span><a name="line.813"></a>
-<span class="sourceLineNo">814</span>  private String getStrForMax(final int max) {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    return max == Integer.MAX_VALUE ? "NO_LIMIT" : Integer.toString(max);<a name="line.815"></a>
-<span class="sourceLineNo">816</span>  }<a name="line.816"></a>
-<span class="sourceLineNo">817</span><a name="line.817"></a>
-<span class="sourceLineNo">818</span>  /** Returns A copy of the internal list of online servers. */<a name="line.818"></a>
-<span class="sourceLineNo">819</span>  public List&lt;ServerName&gt; getOnlineServersList() {<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    // TODO: optimize the load balancer call so we don't need to make a new list<a name="line.820"></a>
-<span class="sourceLineNo">821</span>    // TODO: FIX. THIS IS POPULAR CALL.<a name="line.821"></a>
-<span class="sourceLineNo">822</span>    return new ArrayList&lt;&gt;(this.onlineServers.keySet());<a name="line.822"></a>
-<span class="sourceLineNo">823</span>  }<a name="line.823"></a>
-<span class="sourceLineNo">824</span><a name="line.824"></a>
-<span class="sourceLineNo">825</span>  /**<a name="line.825"></a>
-<span class="sourceLineNo">826</span>   * @param keys                 The target server name<a name="line.826"></a>
-<span class="sourceLineNo">827</span>   * @param idleServerPredicator Evaluates the server on the given load<a name="line.827"></a>
-<span class="sourceLineNo">828</span>   * @return A copy of the internal list of online servers matched by the predicator<a name="line.828"></a>
-<span class="sourceLineNo">829</span>   */<a name="line.829"></a>
-<span class="sourceLineNo">830</span>  public List&lt;ServerName&gt; getOnlineServersListWithPredicator(List&lt;ServerName&gt; keys,<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    Predicate&lt;ServerMetrics&gt; idleServerPredicator) {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>    List&lt;ServerName&gt; names = new ArrayList&lt;&gt;();<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    if (keys != null &amp;&amp; idleServerPredicator != null) {<a name="line.833"></a>
-<span class="sourceLineNo">834</span>      keys.forEach(name -&gt; {<a name="line.834"></a>
-<span class="sourceLineNo">835</span>        ServerMetrics load = onlineServers.get(name);<a name="line.835"></a>
-<span class="sourceLineNo">836</span>        if (load != null) {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>          if (idleServerPredicator.test(load)) {<a name="line.837"></a>
-<span class="sourceLineNo">838</span>            names.add(name);<a name="line.838"></a>
-<span class="sourceLineNo">839</span>          }<a name="line.839"></a>
-<span class="sourceLineNo">840</span>        }<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      });<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    return names;<a name="line.843"></a>
-<span class="sourceLineNo">844</span>  }<a name="line.844"></a>
-<span class="sourceLineNo">845</span><a name="line.845"></a>
-<span class="sourceLineNo">846</span>  /** Returns A copy of the internal list of draining servers. */<a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public List&lt;ServerName&gt; getDrainingServersList() {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    return new ArrayList&lt;&gt;(this.drainingServers);<a name="line.848"></a>
+<span class="sourceLineNo">222</span>    // if use-ip is enabled, we will use ip to expose Master/RS service for client,<a name="line.222"></a>
+<span class="sourceLineNo">223</span>    // see HBASE-27304 for details.<a name="line.223"></a>
+<span class="sourceLineNo">224</span>    boolean useIp = master.getConfiguration().getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY,<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>    String isaHostName = useIp ? ia.getHostAddress() : ia.getHostName();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    final String hostname =<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      request.hasUseThisHostnameInstead() ? request.getUseThisHostnameInstead() : isaHostName;<a name="line.228"></a>
+<span class="sourceLineNo">229</span>    ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    checkClockSkew(sn, request.getServerCurrentTime());<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    checkIsDead(sn, "STARTUP");<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    if (!checkAndRecordNewServer(sn, ServerMetricsBuilder.of(sn, versionNumber, version))) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      LOG.warn(<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        "THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);<a name="line.234"></a>
+<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    storage.started(sn);<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    return sn;<a name="line.237"></a>
+<span class="sourceLineNo">238</span>  }<a name="line.238"></a>
+<span class="sourceLineNo">239</span><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Updates last flushed sequence Ids for the regions on server sn<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   */<a name="line.242"></a>
+<span class="sourceLineNo">243</span>  private void updateLastFlushedSequenceIds(ServerName sn, ServerMetrics hsl) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    for (Entry&lt;byte[], RegionMetrics&gt; entry : hsl.getRegionMetrics().entrySet()) {<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey()));<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.246"></a>
+<span class="sourceLineNo">247</span>      long l = entry.getValue().getCompletedSequenceId();<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      // Don't let smaller sequence ids override greater sequence ids.<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      if (LOG.isTraceEnabled()) {<a name="line.249"></a>
+<span class="sourceLineNo">250</span>        LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue<a name="line.250"></a>
+<span class="sourceLineNo">251</span>          + ", completeSequenceId=" + l);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>      }<a name="line.252"></a>
+<span class="sourceLineNo">253</span>      if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue)) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>        flushedSequenceIdByRegion.put(encodedRegionName, l);<a name="line.254"></a>
+<span class="sourceLineNo">255</span>      } else if (l != HConstants.NO_SEQNUM &amp;&amp; l &lt; existingValue) {<a name="line.255"></a>
+<span class="sourceLineNo">256</span>        LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l<a name="line.256"></a>
+<span class="sourceLineNo">257</span>          + ") that is less than the previous last flushed sequence id (" + existingValue<a name="line.257"></a>
+<span class="sourceLineNo">258</span>          + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring.");<a name="line.258"></a>
+<span class="sourceLineNo">259</span>      }<a name="line.259"></a>
+<span class="sourceLineNo">260</span>      ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>        computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.261"></a>
+<span class="sourceLineNo">262</span>          () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      for (Entry&lt;byte[], Long&gt; storeSeqId : entry.getValue().getStoreSequenceId().entrySet()) {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>        byte[] family = storeSeqId.getKey();<a name="line.264"></a>
+<span class="sourceLineNo">265</span>        existingValue = storeFlushedSequenceId.get(family);<a name="line.265"></a>
+<span class="sourceLineNo">266</span>        l = storeSeqId.getValue();<a name="line.266"></a>
+<span class="sourceLineNo">267</span>        if (LOG.isTraceEnabled()) {<a name="line.267"></a>
+<span class="sourceLineNo">268</span>          LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family)<a name="line.268"></a>
+<span class="sourceLineNo">269</span>            + ", existingValue=" + existingValue + ", completeSequenceId=" + l);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>        }<a name="line.270"></a>
+<span class="sourceLineNo">271</span>        // Don't let smaller sequence ids override greater sequence ids.<a name="line.271"></a>
+<span class="sourceLineNo">272</span>        if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue.longValue())) {<a name="line.272"></a>
+<span class="sourceLineNo">273</span>          storeFlushedSequenceId.put(family, l);<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        }<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      }<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    }<a name="line.276"></a>
+<span class="sourceLineNo">277</span>  }<a name="line.277"></a>
+<span class="sourceLineNo">278</span><a name="line.278"></a>
+<span class="sourceLineNo">279</span>  public void regionServerReport(ServerName sn, ServerMetrics sl) throws YouAreDeadException {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>    checkIsDead(sn, "REPORT");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>    if (null == this.onlineServers.replace(sn, sl)) {<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      // Already have this host+port combo and its just different start code?<a name="line.282"></a>
+<span class="sourceLineNo">283</span>      // Just let the server in. Presume master joining a running cluster.<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      // recordNewServer is what happens at the end of reportServerStartup.<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      // The only thing we are skipping is passing back to the regionserver<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      // the ServerName to use. Here we presume a master has already done<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      // that so we'll press on with whatever it gave us for ServerName.<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      if (!checkAndRecordNewServer(sn, sl)) {<a name="line.288"></a>
+<span class="sourceLineNo">289</span>        LOG.info("RegionServerReport ignored, could not record the server: " + sn);<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        return; // Not recorded, so no need to move on<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      }<a name="line.291"></a>
+<span class="sourceLineNo">292</span>    }<a name="line.292"></a>
+<span class="sourceLineNo">293</span>    updateLastFlushedSequenceIds(sn, sl);<a name="line.293"></a>
+<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
+<span class="sourceLineNo">295</span><a name="line.295"></a>
+<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
+<span class="sourceLineNo">297</span>   * Check is a server of same host and port already exists, if not, or the existed one got a<a name="line.297"></a>
+<span class="sourceLineNo">298</span>   * smaller start code, record it.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>   * @param serverName the server to check and record<a name="line.299"></a>
+<span class="sourceLineNo">300</span>   * @param sl         the server load on the server<a name="line.300"></a>
+<span class="sourceLineNo">301</span>   * @return true if the server is recorded, otherwise, false<a name="line.301"></a>
+<span class="sourceLineNo">302</span>   */<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  boolean checkAndRecordNewServer(final ServerName serverName, final ServerMetrics sl) {<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    ServerName existingServer = null;<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    synchronized (this.onlineServers) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      existingServer = findServerWithSameHostnamePortWithLock(serverName);<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      if (existingServer != null &amp;&amp; (existingServer.getStartcode() &gt; serverName.getStartcode())) {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>        LOG.info("Server serverName=" + serverName + " rejected; we already have "<a name="line.308"></a>
+<span class="sourceLineNo">309</span>          + existingServer.toString() + " registered with same hostname and port");<a name="line.309"></a>
+<span class="sourceLineNo">310</span>        return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>      }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>      recordNewServerWithLock(serverName, sl);<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>    // Tell our listeners that a server was added<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    if (!this.listeners.isEmpty()) {<a name="line.316"></a>
+<span class="sourceLineNo">317</span>      for (ServerListener listener : this.listeners) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>        listener.serverAdded(serverName);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>      }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>    // Note that we assume that same ts means same server, and don't expire in that case.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    // TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    if (existingServer != null &amp;&amp; (existingServer.getStartcode() &lt; serverName.getStartcode())) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      LOG.info("Triggering server recovery; existingServer " + existingServer<a name="line.325"></a>
+<span class="sourceLineNo">326</span>        + " looks stale, new server:" + serverName);<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      expireServer(existingServer);<a name="line.327"></a>
+<span class="sourceLineNo">328</span>    }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    return true;<a name="line.329"></a>
+<span class="sourceLineNo">330</span>  }<a name="line.330"></a>
+<span class="sourceLineNo">331</span><a name="line.331"></a>
+<span class="sourceLineNo">332</span>  /**<a name="line.332"></a>
+<span class="sourceLineNo">333</span>   * Find out the region servers crashed between the crash of the previous master instance and the<a name="line.333"></a>
+<span class="sourceLineNo">334</span>   * current master instance and schedule SCP for them.<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * &lt;p/&gt;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * Since the {@code RegionServerTracker} has already helped us to construct the online servers set<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * by scanning zookeeper, now we can compare the online servers with {@code liveServersFromWALDir}<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   * to find out whether there are servers which are already dead.<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * &lt;p/&gt;<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * Must be called inside the initialization method of {@code RegionServerTracker} to avoid<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   * concurrency issue.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>   * @param deadServersFromPE     the region servers which already have a SCP associated.<a name="line.342"></a>
+<span class="sourceLineNo">343</span>   * @param liveServersFromWALDir the live region servers from wal directory.<a name="line.343"></a>
+<span class="sourceLineNo">344</span>   */<a name="line.344"></a>
+<span class="sourceLineNo">345</span>  void findDeadServersAndProcess(Set&lt;ServerName&gt; deadServersFromPE,<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    Set&lt;ServerName&gt; liveServersFromWALDir) {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    deadServersFromPE.forEach(deadservers::putIfAbsent);<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    liveServersFromWALDir.stream().filter(sn -&gt; !onlineServers.containsKey(sn))<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      .forEach(this::expireServer);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>  }<a name="line.350"></a>
+<span class="sourceLineNo">351</span><a name="line.351"></a>
+<span class="sourceLineNo">352</span>  /**<a name="line.352"></a>
+<span class="sourceLineNo">353</span>   * Checks if the clock skew between the server and the master. If the clock skew exceeds the<a name="line.353"></a>
+<span class="sourceLineNo">354</span>   * configured max, it will throw an exception; if it exceeds the configured warning threshold, it<a name="line.354"></a>
+<span class="sourceLineNo">355</span>   * will log a warning but start normally.<a name="line.355"></a>
+<span class="sourceLineNo">356</span>   * @param serverName Incoming servers's name n * @throws ClockOutOfSyncException if the skew<a name="line.356"></a>
+<span class="sourceLineNo">357</span>   *                   exceeds the configured max value<a name="line.357"></a>
+<span class="sourceLineNo">358</span>   */<a name="line.358"></a>
+<span class="sourceLineNo">359</span>  private void checkClockSkew(final ServerName serverName, final long serverCurrentTime)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    throws ClockOutOfSyncException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    long skew = Math.abs(EnvironmentEdgeManager.currentTime() - serverCurrentTime);<a name="line.361"></a>
+<span class="sourceLineNo">362</span>    if (skew &gt; maxSkew) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      String message = "Server " + serverName + " has been "<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        + "rejected; Reported time is too far out of sync with master.  " + "Time difference of "<a name="line.364"></a>
+<span class="sourceLineNo">365</span>        + skew + "ms &gt; max allowed of " + maxSkew + "ms";<a name="line.365"></a>
+<span class="sourceLineNo">366</span>      LOG.warn(message);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>      throw new ClockOutOfSyncException(message);<a name="line.367"></a>
+<span class="sourceLineNo">368</span>    } else if (skew &gt; warningSkew) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      String message = "Reported time for server " + serverName + " is out of sync with master "<a name="line.369"></a>
+<span class="sourceLineNo">370</span>        + "by " + skew + "ms. (Warning threshold is " + warningSkew + "ms; " + "error threshold is "<a name="line.370"></a>
+<span class="sourceLineNo">371</span>        + maxSkew + "ms)";<a name="line.371"></a>
+<span class="sourceLineNo">372</span>      LOG.warn(message);<a name="line.372"></a>
+<span class="sourceLineNo">373</span>    }<a name="line.373"></a>
+<span class="sourceLineNo">374</span>  }<a name="line.374"></a>
+<span class="sourceLineNo">375</span><a name="line.375"></a>
+<span class="sourceLineNo">376</span>  /**<a name="line.376"></a>
+<span class="sourceLineNo">377</span>   * Called when RegionServer first reports in for duty and thereafter each time it heartbeats to<a name="line.377"></a>
+<span class="sourceLineNo">378</span>   * make sure it is has not been figured for dead. If this server is on the dead list, reject it<a name="line.378"></a>
+<span class="sourceLineNo">379</span>   * with a YouAreDeadException. If it was dead but came back with a new start code, remove the old<a name="line.379"></a>
+<span class="sourceLineNo">380</span>   * entry from the dead list.<a name="line.380"></a>
+<span class="sourceLineNo">381</span>   * @param what START or REPORT<a name="line.381"></a>
+<span class="sourceLineNo">382</span>   */<a name="line.382"></a>
+<span class="sourceLineNo">383</span>  private void checkIsDead(final ServerName serverName, final String what)<a name="line.383"></a>
+<span class="sourceLineNo">384</span>    throws YouAreDeadException {<a name="line.384"></a>
+<span class="sourceLineNo">385</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.385"></a>
+<span class="sourceLineNo">386</span>      // Exact match: host name, port and start code all match with existing one of the<a name="line.386"></a>
+<span class="sourceLineNo">387</span>      // dead servers. So, this server must be dead. Tell it to kill itself.<a name="line.387"></a>
+<span class="sourceLineNo">388</span>      String message =<a name="line.388"></a>
+<span class="sourceLineNo">389</span>        "Server " + what + " rejected; currently processing " + serverName + " as dead server";<a name="line.389"></a>
+<span class="sourceLineNo">390</span>      LOG.debug(message);<a name="line.390"></a>
+<span class="sourceLineNo">391</span>      throw new YouAreDeadException(message);<a name="line.391"></a>
+<span class="sourceLineNo">392</span>    }<a name="line.392"></a>
+<span class="sourceLineNo">393</span>    // Remove dead server with same hostname and port of newly checking in rs after master<a name="line.393"></a>
+<span class="sourceLineNo">394</span>    // initialization. See HBASE-5916 for more information.<a name="line.394"></a>
+<span class="sourceLineNo">395</span>    if (<a name="line.395"></a>
+<span class="sourceLineNo">396</span>      (this.master == null || this.master.isInitialized())<a name="line.396"></a>
+<span class="sourceLineNo">397</span>        &amp;&amp; this.deadservers.cleanPreviousInstance(serverName)<a name="line.397"></a>
+<span class="sourceLineNo">398</span>    ) {<a name="line.398"></a>
+<span class="sourceLineNo">399</span>      // This server has now become alive after we marked it as dead.<a name="line.399"></a>
+<span class="sourceLineNo">400</span>      // We removed it's previous entry from the dead list to reflect it.<a name="line.400"></a>
+<span class="sourceLineNo">401</span>      LOG.debug("{} {} came back up, removed it from the dead servers list", what, serverName);<a name="line.401"></a>
+<span class="sourceLineNo">402</span>    }<a name="line.402"></a>
+<span class="sourceLineNo">403</span>  }<a name="line.403"></a>
+<span class="sourceLineNo">404</span><a name="line.404"></a>
+<span class="sourceLineNo">405</span>  /**<a name="line.405"></a>
+<span class="sourceLineNo">406</span>   * Assumes onlineServers is locked.<a name="line.406"></a>
+<span class="sourceLineNo">407</span>   * @return ServerName with matching hostname and port.<a name="line.407"></a>
+<span class="sourceLineNo">408</span>   */<a name="line.408"></a>
+<span class="sourceLineNo">409</span>  private ServerName findServerWithSameHostnamePortWithLock(final ServerName serverName) {<a name="line.409"></a>
+<span class="sourceLineNo">410</span>    ServerName end =<a name="line.410"></a>
+<span class="sourceLineNo">411</span>      ServerName.valueOf(serverName.getHostname(), serverName.getPort(), Long.MAX_VALUE);<a name="line.411"></a>
+<span class="sourceLineNo">412</span><a name="line.412"></a>
+<span class="sourceLineNo">413</span>    ServerName r = onlineServers.lowerKey(end);<a name="line.413"></a>
+<span class="sourceLineNo">414</span>    if (r != null) {<a name="line.414"></a>
+<span class="sourceLineNo">415</span>      if (ServerName.isSameAddress(r, serverName)) {<a name="line.415"></a>
+<span class="sourceLineNo">416</span>        return r;<a name="line.416"></a>
+<span class="sourceLineNo">417</span>      }<a name="line.417"></a>
+<span class="sourceLineNo">418</span>    }<a name="line.418"></a>
+<span class="sourceLineNo">419</span>    return null;<a name="line.419"></a>
+<span class="sourceLineNo">420</span>  }<a name="line.420"></a>
+<span class="sourceLineNo">421</span><a name="line.421"></a>
+<span class="sourceLineNo">422</span>  /**<a name="line.422"></a>
+<span class="sourceLineNo">423</span>   * Adds the onlineServers list. onlineServers should be locked.<a name="line.423"></a>
+<span class="sourceLineNo">424</span>   * @param serverName The remote servers name.<a name="line.424"></a>
+<span class="sourceLineNo">425</span>   */<a name="line.425"></a>
+<span class="sourceLineNo">426</span>  void recordNewServerWithLock(final ServerName serverName, final ServerMetrics sl) {<a name="line.426"></a>
+<span class="sourceLineNo">427</span>    LOG.info("Registering regionserver=" + serverName);<a name="line.427"></a>
+<span class="sourceLineNo">428</span>    this.onlineServers.put(serverName, sl);<a name="line.428"></a>
+<span class="sourceLineNo">429</span>  }<a name="line.429"></a>
+<span class="sourceLineNo">430</span><a name="line.430"></a>
+<span class="sourceLineNo">431</span>  public ConcurrentNavigableMap&lt;byte[], Long&gt; getFlushedSequenceIdByRegion() {<a name="line.431"></a>
+<span class="sourceLineNo">432</span>    return flushedSequenceIdByRegion;<a name="line.432"></a>
+<span class="sourceLineNo">433</span>  }<a name="line.433"></a>
+<span class="sourceLineNo">434</span><a name="line.434"></a>
+<span class="sourceLineNo">435</span>  public RegionStoreSequenceIds getLastFlushedSequenceId(byte[] encodedRegionName) {<a name="line.435"></a>
+<span class="sourceLineNo">436</span>    RegionStoreSequenceIds.Builder builder = RegionStoreSequenceIds.newBuilder();<a name="line.436"></a>
+<span class="sourceLineNo">437</span>    Long seqId = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.437"></a>
+<span class="sourceLineNo">438</span>    builder.setLastFlushedSequenceId(seqId != null ? seqId.longValue() : HConstants.NO_SEQNUM);<a name="line.438"></a>
+<span class="sourceLineNo">439</span>    Map&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.439"></a>
+<span class="sourceLineNo">440</span>      storeFlushedSequenceIdsByRegion.get(encodedRegionName);<a name="line.440"></a>
+<span class="sourceLineNo">441</span>    if (storeFlushedSequenceId != null) {<a name="line.441"></a>
+<span class="sourceLineNo">442</span>      for (Map.Entry&lt;byte[], Long&gt; entry : storeFlushedSequenceId.entrySet()) {<a name="line.442"></a>
+<span class="sourceLineNo">443</span>        builder.addStoreSequenceId(StoreSequenceId.newBuilder()<a name="line.443"></a>
+<span class="sourceLineNo">444</span>          .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey()))<a name="line.444"></a>
+<span class="sourceLineNo">445</span>          .setSequenceId(entry.getValue().longValue()).build());<a name="line.445"></a>
+<span class="sourceLineNo">446</span>      }<a name="line.446"></a>
+<span class="sourceLineNo">447</span>    }<a name="line.447"></a>
+<span class="sourceLineNo">448</span>    return builder.build();<a name="line.448"></a>
+<span class="sourceLineNo">449</span>  }<a name="line.449"></a>
+<span class="sourceLineNo">450</span><a name="line.450"></a>
+<span class="sourceLineNo">451</span>  /**<a name="line.451"></a>
+<span class="sourceLineNo">452</span>   * n * @return ServerMetrics if serverName is known else null<a name="line.452"></a>
+<span class="sourceLineNo">453</span>   */<a name="line.453"></a>
+<span class="sourceLineNo">454</span>  public ServerMetrics getLoad(final ServerName serverName) {<a name="line.454"></a>
+<span class="sourceLineNo">455</span>    return this.onlineServers.get(serverName);<a name="line.455"></a>
+<span class="sourceLineNo">456</span>  }<a name="line.456"></a>
+<span class="sourceLineNo">457</span><a name="line.457"></a>
+<span class="sourceLineNo">458</span>  /**<a name="line.458"></a>
+<span class="sourceLineNo">459</span>   * Compute the average load across all region servers. Currently, this uses a very naive<a name="line.459"></a>
+<span class="sourceLineNo">460</span>   * computation - just uses the number of regions being served, ignoring stats about number of<a name="line.460"></a>
+<span class="sourceLineNo">461</span>   * requests.<a name="line.461"></a>
+<span class="sourceLineNo">462</span>   * @return the average load<a name="line.462"></a>
+<span class="sourceLineNo">463</span>   */<a name="line.463"></a>
+<span class="sourceLineNo">464</span>  public double getAverageLoad() {<a name="line.464"></a>
+<span class="sourceLineNo">465</span>    int totalLoad = 0;<a name="line.465"></a>
+<span class="sourceLineNo">466</span>    int numServers = 0;<a name="line.466"></a>
+<span class="sourceLineNo">467</span>    for (ServerMetrics sl : this.onlineServers.values()) {<a name="line.467"></a>
+<span class="sourceLineNo">468</span>      numServers++;<a name="line.468"></a>
+<span class="sourceLineNo">469</span>      totalLoad += sl.getRegionMetrics().size();<a name="line.469"></a>
+<span class="sourceLineNo">470</span>    }<a name="line.470"></a>
+<span class="sourceLineNo">471</span>    return numServers == 0 ? 0 : (double) totalLoad / (double) numServers;<a name="line.471"></a>
+<span class="sourceLineNo">472</span>  }<a name="line.472"></a>
+<span class="sourceLineNo">473</span><a name="line.473"></a>
+<span class="sourceLineNo">474</span>  /** Returns the count of active regionservers */<a name="line.474"></a>
+<span class="sourceLineNo">475</span>  public int countOfRegionServers() {<a name="line.475"></a>
+<span class="sourceLineNo">476</span>    // Presumes onlineServers is a concurrent map<a name="line.476"></a>
+<span class="sourceLineNo">477</span>    return this.onlineServers.size();<a name="line.477"></a>
+<span class="sourceLineNo">478</span>  }<a name="line.478"></a>
+<span class="sourceLineNo">479</span><a name="line.479"></a>
+<span class="sourceLineNo">480</span>  /** Returns Read-only map of servers to serverinfo */<a name="line.480"></a>
+<span class="sourceLineNo">481</span>  public Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {<a name="line.481"></a>
+<span class="sourceLineNo">482</span>    // Presumption is that iterating the returned Map is OK.<a name="line.482"></a>
+<span class="sourceLineNo">483</span>    synchronized (this.onlineServers) {<a name="line.483"></a>
+<span class="sourceLineNo">484</span>      return Collections.unmodifiableMap(this.onlineServers);<a name="line.484"></a>
+<span class="sourceLineNo">485</span>    }<a name="line.485"></a>
+<span class="sourceLineNo">486</span>  }<a name="line.486"></a>
+<span class="sourceLineNo">487</span><a name="line.487"></a>
+<span class="sourceLineNo">488</span>  public DeadServer getDeadServers() {<a name="line.488"></a>
+<span class="sourceLineNo">489</span>    return this.deadservers;<a name="line.489"></a>
+<span class="sourceLineNo">490</span>  }<a name="line.490"></a>
+<span class="sourceLineNo">491</span><a name="line.491"></a>
+<span class="sourceLineNo">492</span>  /**<a name="line.492"></a>
+<span class="sourceLineNo">493</span>   * Checks if any dead servers are currently in progress.<a name="line.493"></a>
+<span class="sourceLineNo">494</span>   * @return true if any RS are being processed as dead, false if not<a name="line.494"></a>
+<span class="sourceLineNo">495</span>   */<a name="line.495"></a>
+<span class="sourceLineNo">496</span>  public boolean areDeadServersInProgress() throws IOException {<a name="line.496"></a>
+<span class="sourceLineNo">497</span>    return master.getProcedures().stream()<a name="line.497"></a>
+<span class="sourceLineNo">498</span>      .anyMatch(p -&gt; !p.isFinished() &amp;&amp; p instanceof ServerCrashProcedure);<a name="line.498"></a>
+<span class="sourceLineNo">499</span>  }<a name="line.499"></a>
+<span class="sourceLineNo">500</span><a name="line.500"></a>
+<span class="sourceLineNo">501</span>  void letRegionServersShutdown() {<a name="line.501"></a>
+<span class="sourceLineNo">502</span>    long previousLogTime = 0;<a name="line.502"></a>
+<span class="sourceLineNo">503</span>    ServerName sn = master.getServerName();<a name="line.503"></a>
+<span class="sourceLineNo">504</span>    ZKWatcher zkw = master.getZooKeeper();<a name="line.504"></a>
+<span class="sourceLineNo">505</span>    int onlineServersCt;<a name="line.505"></a>
+<span class="sourceLineNo">506</span>    while ((onlineServersCt = onlineServers.size()) &gt; 0) {<a name="line.506"></a>
+<span class="sourceLineNo">507</span>      if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {<a name="line.507"></a>
+<span class="sourceLineNo">508</span>        Set&lt;ServerName&gt; remainingServers = onlineServers.keySet();<a name="line.508"></a>
+<span class="sourceLineNo">509</span>        synchronized (onlineServers) {<a name="line.509"></a>
+<span class="sourceLineNo">510</span>          if (remainingServers.size() == 1 &amp;&amp; remainingServers.contains(sn)) {<a name="line.510"></a>
+<span class="sourceLineNo">511</span>            // Master will delete itself later.<a name="line.511"></a>
+<span class="sourceLineNo">512</span>            return;<a name="line.512"></a>
+<span class="sourceLineNo">513</span>          }<a name="line.513"></a>
+<span class="sourceLineNo">514</span>        }<a name="line.514"></a>
+<span class="sourceLineNo">515</span>        StringBuilder sb = new StringBuilder();<a name="line.515"></a>
+<span class="sourceLineNo">516</span>        // It's ok here to not sync on onlineServers - merely logging<a name="line.516"></a>
+<span class="sourceLineNo">517</span>        for (ServerName key : remainingServers) {<a name="line.517"></a>
+<span class="sourceLineNo">518</span>          if (sb.length() &gt; 0) {<a name="line.518"></a>
+<span class="sourceLineNo">519</span>            sb.append(", ");<a name="line.519"></a>
+<span class="sourceLineNo">520</span>          }<a name="line.520"></a>
+<span class="sourceLineNo">521</span>          sb.append(key);<a name="line.521"></a>
+<span class="sourceLineNo">522</span>        }<a name="line.522"></a>
+<span class="sourceLineNo">523</span>        LOG.info("Waiting on regionserver(s) " + sb.toString());<a name="line.523"></a>
+<span class="sourceLineNo">524</span>        previousLogTime = EnvironmentEdgeManager.currentTime();<a name="line.524"></a>
+<span class="sourceLineNo">525</span>      }<a name="line.525"></a>
+<span class="sourceLineNo">526</span><a name="line.526"></a>
+<span class="sourceLineNo">527</span>      try {<a name="line.527"></a>
+<span class="sourceLineNo">528</span>        List&lt;String&gt; servers = getRegionServersInZK(zkw);<a name="line.528"></a>
+<span class="sourceLineNo">529</span>        if (<a name="line.529"></a>
+<span class="sourceLineNo">530</span>          servers == null || servers.isEmpty()<a name="line.530"></a>
+<span class="sourceLineNo">531</span>            || (servers.size() == 1 &amp;&amp; servers.contains(sn.toString()))<a name="line.531"></a>
+<span class="sourceLineNo">532</span>        ) {<a name="line.532"></a>
+<span class="sourceLineNo">533</span>          LOG.info("ZK shows there is only the master self online, exiting now");<a name="line.533"></a>
+<span class="sourceLineNo">534</span>          // Master could have lost some ZK events, no need to wait more.<a name="line.534"></a>
+<span class="sourceLineNo">535</span>          break;<a name="line.535"></a>
+<span class="sourceLineNo">536</span>        }<a name="line.536"></a>
+<span class="sourceLineNo">537</span>      } catch (KeeperException ke) {<a name="line.537"></a>
+<span class="sourceLineNo">538</span>        LOG.warn("Failed to list regionservers", ke);<a name="line.538"></a>
+<span class="sourceLineNo">539</span>        // ZK is malfunctioning, don't hang here<a name="line.539"></a>
+<span class="sourceLineNo">540</span>        break;<a name="line.540"></a>
+<span class="sourceLineNo">541</span>      }<a name="line.541"></a>
+<span class="sourceLineNo">542</span>      synchronized (onlineServers) {<a name="line.542"></a>
+<span class="sourceLineNo">543</span>        try {<a name="line.543"></a>
+<span class="sourceLineNo">544</span>          if (onlineServersCt == onlineServers.size()) onlineServers.wait(100);<a name="line.544"></a>
+<span class="sourceLineNo">545</span>        } catch (InterruptedException ignored) {<a name="line.545"></a>
+<span class="sourceLineNo">546</span>          // continue<a name="line.546"></a>
+<span class="sourceLineNo">547</span>        }<a name="line.547"></a>
+<span class="sourceLineNo">548</span>      }<a name="line.548"></a>
+<span class="sourceLineNo">549</span>    }<a name="line.549"></a>
+<span class="sourceLineNo">550</span>  }<a name="line.550"></a>
+<span class="sourceLineNo">551</span><a name="line.551"></a>
+<span class="sourceLineNo">552</span>  private List&lt;String&gt; getRegionServersInZK(final ZKWatcher zkw) throws KeeperException {<a name="line.552"></a>
+<span class="sourceLineNo">553</span>    return ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode);<a name="line.553"></a>
+<span class="sourceLineNo">554</span>  }<a name="line.554"></a>
+<span class="sourceLineNo">555</span><a name="line.555"></a>
+<span class="sourceLineNo">556</span>  /**<a name="line.556"></a>
+<span class="sourceLineNo">557</span>   * Expire the passed server. Add it to list of dead servers and queue a shutdown processing.<a name="line.557"></a>
+<span class="sourceLineNo">558</span>   * @return pid if we queued a ServerCrashProcedure else {@link Procedure#NO_PROC_ID} if we did not<a name="line.558"></a>
+<span class="sourceLineNo">559</span>   *         (could happen for many reasons including the fact that its this server that is going<a name="line.559"></a>
+<span class="sourceLineNo">560</span>   *         down or we already have queued an SCP for this server or SCP processing is currently<a name="line.560"></a>
+<span class="sourceLineNo">561</span>   *         disabled because we are in startup phase).<a name="line.561"></a>
+<span class="sourceLineNo">562</span>   */<a name="line.562"></a>
+<span class="sourceLineNo">563</span>  // Redo test so we can make this protected.<a name="line.563"></a>
+<span class="sourceLineNo">564</span>  public synchronized long expireServer(final ServerName serverName) {<a name="line.564"></a>
+<span class="sourceLineNo">565</span>    return expireServer(serverName, false);<a name="line.565"></a>
+<span class="sourceLineNo">566</span><a name="line.566"></a>
+<span class="sourceLineNo">567</span>  }<a name="line.567"></a>
+<span class="sourceLineNo">568</span><a name="line.568"></a>
+<span class="sourceLineNo">569</span>  synchronized long expireServer(final ServerName serverName, boolean force) {<a name="line.569"></a>
+<span class="sourceLineNo">570</span>    // THIS server is going down... can't handle our own expiration.<a name="line.570"></a>
+<span class="sourceLineNo">571</span>    if (serverName.equals(master.getServerName())) {<a name="line.571"></a>
+<span class="sourceLineNo">572</span>      if (!(master.isAborted() || master.isStopped())) {<a name="line.572"></a>
+<span class="sourceLineNo">573</span>        master.stop("We lost our znode?");<a name="line.573"></a>
+<span class="sourceLineNo">574</span>      }<a name="line.574"></a>
+<span class="sourceLineNo">575</span>      return Procedure.NO_PROC_ID;<a name="line.575"></a>
+<span class="sourceLineNo">576</span>    }<a name="line.576"></a>
+<span class="sourceLineNo">577</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.577"></a>
+<span class="sourceLineNo">578</span>      LOG.warn("Expiration called on {} but already in DeadServer", serverName);<a name="line.578"></a>
+<span class="sourceLineNo">579</span>      return Procedure.NO_PROC_ID;<a name="line.579"></a>
+<span class="sourceLineNo">580</span>    }<a name="line.580"></a>
+<span class="sourceLineNo">581</span>    moveFromOnlineToDeadServers(serverName);<a name="line.581"></a>
+<span class="sourceLineNo">582</span><a name="line.582"></a>
+<span class="sourceLineNo">583</span>    // If server is in draining mode, remove corresponding znode<a name="line.583"></a>
+<span class="sourceLineNo">584</span>    // In some tests, the mocked HM may not have ZK Instance, hence null check<a name="line.584"></a>
+<span class="sourceLineNo">585</span>    if (master.getZooKeeper() != null) {<a name="line.585"></a>
+<span class="sourceLineNo">586</span>      String drainingZnode = ZNodePaths<a name="line.586"></a>
+<span class="sourceLineNo">587</span>        .joinZNode(master.getZooKeeper().getZNodePaths().drainingZNode, serverName.getServerName());<a name="line.587"></a>
+<span class="sourceLineNo">588</span>      try {<a name="line.588"></a>
+<span class="sourceLineNo">589</span>        ZKUtil.deleteNodeFailSilent(master.getZooKeeper(), drainingZnode);<a name="line.589"></a>
+<span class="sourceLineNo">590</span>      } catch (KeeperException e) {<a name="line.590"></a>
+<span class="sourceLineNo">591</span>        LOG.warn(<a name="line.591"></a>
+<span class="sourceLineNo">592</span>          "Error deleting the draining znode for stopping server " + serverName.getServerName(), e);<a name="line.592"></a>
+<span class="sourceLineNo">593</span>      }<a name="line.593"></a>
+<span class="sourceLineNo">594</span>    }<a name="line.594"></a>
+<span class="sourceLineNo">595</span><a name="line.595"></a>
+<span class="sourceLineNo">596</span>    // If cluster is going down, yes, servers are going to be expiring; don't<a name="line.596"></a>
+<span class="sourceLineNo">597</span>    // process as a dead server<a name="line.597"></a>
+<span class="sourceLineNo">598</span>    if (isClusterShutdown()) {<a name="line.598"></a>
+<span class="sourceLineNo">599</span>      LOG.info("Cluster shutdown set; " + serverName + " expired; onlineServers="<a name="line.599"></a>
+<span class="sourceLineNo">600</span>        + this.onlineServers.size());<a name="line.600"></a>
+<span class="sourceLineNo">601</span>      if (this.onlineServers.isEmpty()) {<a name="line.601"></a>
+<span class="sourceLineNo">602</span>        master.stop("Cluster shutdown set; onlineServer=0");<a name="line.602"></a>
+<span class="sourceLineNo">603</span>      }<a name="line.603"></a>
+<span class="sourceLineNo">604</span>      return Procedure.NO_PROC_ID;<a name="line.604"></a>
+<span class="sourceLineNo">605</span>    }<a name="line.605"></a>
+<span class="sourceLineNo">606</span>    LOG.info("Processing expiration of " + serverName + " on " + this.master.getServerName());<a name="line.606"></a>
+<span class="sourceLineNo">607</span>    long pid = master.getAssignmentManager().submitServerCrash(serverName, true, force);<a name="line.607"></a>
+<span class="sourceLineNo">608</span>    storage.expired(serverName);<a name="line.608"></a>
+<span class="sourceLineNo">609</span>    // Tell our listeners that a server was removed<a name="line.609"></a>
+<span class="sourceLineNo">610</span>    if (!this.listeners.isEmpty()) {<a name="line.610"></a>
+<span class="sourceLineNo">611</span>      this.listeners.stream().forEach(l -&gt; l.serverRemoved(serverName));<a name="line.611"></a>
+<span class="sourceLineNo">612</span>    }<a name="line.612"></a>
+<span class="sourceLineNo">613</span>    // trigger a persist of flushedSeqId<a name="line.613"></a>
+<span class="sourceLineNo">614</span>    if (flushedSeqIdFlusher != null) {<a name="line.614"></a>
+<span class="sourceLineNo">615</span>      flushedSeqIdFlusher.triggerNow();<a name="line.615"></a>
+<span class="sourceLineNo">616</span>    }<a name="line.616"></a>
+<span class="sourceLineNo">617</span>    return pid;<a name="line.617"></a>
+<span class="sourceLineNo">618</span>  }<a name="line.618"></a>
+<span class="sourceLineNo">619</span><a name="line.619"></a>
+<span class="sourceLineNo">620</span>  /**<a name="line.620"></a>
+<span class="sourceLineNo">621</span>   * Called when server has expired.<a name="line.621"></a>
+<span class="sourceLineNo">622</span>   */<a name="line.622"></a>
+<span class="sourceLineNo">623</span>  // Locking in this class needs cleanup.<a name="line.623"></a>
+<span class="sourceLineNo">624</span>  public synchronized void moveFromOnlineToDeadServers(final ServerName sn) {<a name="line.624"></a>
+<span class="sourceLineNo">625</span>    synchronized (this.onlineServers) {<a name="line.625"></a>
+<span class="sourceLineNo">626</span>      boolean online = this.onlineServers.containsKey(sn);<a name="line.626"></a>
+<span class="sourceLineNo">627</span>      if (online) {<a name="line.627"></a>
+<span class="sourceLineNo">628</span>        // Remove the server from the known servers lists and update load info BUT<a name="line.628"></a>
+<span class="sourceLineNo">629</span>        // add to deadservers first; do this so it'll show in dead servers list if<a name="line.629"></a>
+<span class="sourceLineNo">630</span>        // not in online servers list.<a name="line.630"></a>
+<span class="sourceLineNo">631</span>        this.deadservers.putIfAbsent(sn);<a name="line.631"></a>
+<span class="sourceLineNo">632</span>        this.onlineServers.remove(sn);<a name="line.632"></a>
+<span class="sourceLineNo">633</span>        onlineServers.notifyAll();<a name="line.633"></a>
+<span class="sourceLineNo">634</span>      } else {<a name="line.634"></a>
+<span class="sourceLineNo">635</span>        // If not online, that is odd but may happen if 'Unknown Servers' -- where meta<a name="line.635"></a>
+<span class="sourceLineNo">636</span>        // has references to servers not online nor in dead servers list. If<a name="line.636"></a>
+<span class="sourceLineNo">637</span>        // 'Unknown Server', don't add to DeadServers else will be there for ever.<a name="line.637"></a>
+<span class="sourceLineNo">638</span>        LOG.trace("Expiration of {} but server not online", sn);<a name="line.638"></a>
+<span class="sourceLineNo">639</span>      }<a name="line.639"></a>
+<span class="sourceLineNo">640</span>    }<a name="line.640"></a>
+<span class="sourceLineNo">641</span>  }<a name="line.641"></a>
+<span class="sourceLineNo">642</span><a name="line.642"></a>
+<span class="sourceLineNo">643</span>  /*<a name="line.643"></a>
+<span class="sourceLineNo">644</span>   * Remove the server from the drain list.<a name="line.644"></a>
+<span class="sourceLineNo">645</span>   */<a name="line.645"></a>
+<span class="sourceLineNo">646</span>  public synchronized boolean removeServerFromDrainList(final ServerName sn) {<a name="line.646"></a>
+<span class="sourceLineNo">647</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.647"></a>
+<span class="sourceLineNo">648</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.648"></a>
+<span class="sourceLineNo">649</span><a name="line.649"></a>
+<span class="sourceLineNo">650</span>    if (!this.isServerOnline(sn)) {<a name="line.650"></a>
+<span class="sourceLineNo">651</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.651"></a>
+<span class="sourceLineNo">652</span>        + "Removing from draining list anyway, as requested.");<a name="line.652"></a>
+<span class="sourceLineNo">653</span>    }<a name="line.653"></a>
+<span class="sourceLineNo">654</span>    // Remove the server from the draining servers lists.<a name="line.654"></a>
+<span class="sourceLineNo">655</span>    return this.drainingServers.remove(sn);<a name="line.655"></a>
+<span class="sourceLineNo">656</span>  }<a name="line.656"></a>
+<span class="sourceLineNo">657</span><a name="line.657"></a>
+<span class="sourceLineNo">658</span>  /**<a name="line.658"></a>
+<span class="sourceLineNo">659</span>   * Add the server to the drain list. n * @return True if the server is added or the server is<a name="line.659"></a>
+<span class="sourceLineNo">660</span>   * already on the drain list.<a name="line.660"></a>
+<span class="sourceLineNo">661</span>   */<a name="line.661"></a>
+<span class="sourceLineNo">662</span>  public synchronized boolean addServerToDrainList(final ServerName sn) {<a name="line.662"></a>
+<span class="sourceLineNo">663</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.663"></a>
+<span class="sourceLineNo">664</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.664"></a>
+<span class="sourceLineNo">665</span><a name="line.665"></a>
+<span class="sourceLineNo">666</span>    if (!this.isServerOnline(sn)) {<a name="line.666"></a>
+<span class="sourceLineNo">667</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.667"></a>
+<span class="sourceLineNo">668</span>        + "Ignoring request to add it to draining list.");<a name="line.668"></a>
+<span class="sourceLineNo">669</span>      return false;<a name="line.669"></a>
+<span class="sourceLineNo">670</span>    }<a name="line.670"></a>
+<span class="sourceLineNo">671</span>    // Add the server to the draining servers lists, if it's not already in<a name="line.671"></a>
+<span class="sourceLineNo">672</span>    // it.<a name="line.672"></a>
+<span class="sourceLineNo">673</span>    if (this.drainingServers.contains(sn)) {<a name="line.673"></a>
+<span class="sourceLineNo">674</span>      LOG.warn("Server " + sn + " is already in the draining server list."<a name="line.674"></a>
+<span class="sourceLineNo">675</span>        + "Ignoring request to add it again.");<a name="line.675"></a>
+<span class="sourceLineNo">676</span>      return true;<a name="line.676"></a>
+<span class="sourceLineNo">677</span>    }<a name="line.677"></a>
+<span class="sourceLineNo">678</span>    LOG.info("Server " + sn + " added to draining server list.");<a name="line.678"></a>
+<span class="sourceLineNo">679</span>    return this.drainingServers.add(sn);<a name="line.679"></a>
+<span class="sourceLineNo">680</span>  }<a name="line.680"></a>
+<span class="sourceLineNo">681</span><a name="line.681"></a>
+<span class="sourceLineNo">682</span>  /**<a name="line.682"></a>
+<span class="sourceLineNo">683</span>   * Contacts a region server and waits up to timeout ms to close the region. This bypasses the<a name="line.683"></a>
+<span class="sourceLineNo">684</span>   * active hmaster. Pass -1 as timeout if you do not want to wait on result.<a name="line.684"></a>
+<span class="sourceLineNo">685</span>   */<a name="line.685"></a>
+<span class="sourceLineNo">686</span>  public static void closeRegionSilentlyAndWait(AsyncClusterConnection connection,<a name="line.686"></a>
+<span class="sourceLineNo">687</span>    ServerName server, RegionInfo region, long timeout) throws IOException, InterruptedException {<a name="line.687"></a>
+<span class="sourceLineNo">688</span>    AsyncRegionServerAdmin admin = connection.getRegionServerAdmin(server);<a name="line.688"></a>
+<span class="sourceLineNo">689</span>    try {<a name="line.689"></a>
+<span class="sourceLineNo">690</span>      FutureUtils.get(<a name="line.690"></a>
+<span class="sourceLineNo">691</span>        admin.closeRegion(ProtobufUtil.buildCloseRegionRequest(server, region.getRegionName())));<a name="line.691"></a>
+<span class="sourceLineNo">692</span>    } catch (IOException e) {<a name="line.692"></a>
+<span class="sourceLineNo">693</span>      LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);<a name="line.693"></a>
+<span class="sourceLineNo">694</span>    }<a name="line.694"></a>
+<span class="sourceLineNo">695</span>    if (timeout &lt; 0) {<a name="line.695"></a>
+<span class="sourceLineNo">696</span>      return;<a name="line.696"></a>
+<span class="sourceLineNo">697</span>    }<a name="line.697"></a>
+<span class="sourceLineNo">698</span>    long expiration = timeout + EnvironmentEdgeManager.currentTime();<a name="line.698"></a>
+<span class="sourceLineNo">699</span>    while (EnvironmentEdgeManager.currentTime() &lt; expiration) {<a name="line.699"></a>
+<span class="sourceLineNo">700</span>      try {<a name="line.700"></a>
+<span class="sourceLineNo">701</span>        RegionInfo rsRegion = ProtobufUtil.toRegionInfo(FutureUtils<a name="line.701"></a>
+<span class="sourceLineNo">702</span>          .get(<a name="line.702"></a>
+<span class="sourceLineNo">703</span>            admin.getRegionInfo(RequestConverter.buildGetRegionInfoRequest(region.getRegionName())))<a name="line.703"></a>
+<span class="sourceLineNo">704</span>          .getRegionInfo());<a name="line.704"></a>
+<span class="sourceLineNo">705</span>        if (rsRegion == null) {<a name="line.705"></a>
+<span class="sourceLineNo">706</span>          return;<a name="line.706"></a>
+<span class="sourceLineNo">707</span>        }<a name="line.707"></a>
+<span class="sourceLineNo">708</span>      } catch (IOException ioe) {<a name="line.708"></a>
+<span class="sourceLineNo">709</span>        if (<a name="line.709"></a>
+<span class="sourceLineNo">710</span>          ioe instanceof NotServingRegionException<a name="line.710"></a>
+<span class="sourceLineNo">711</span>            || (ioe instanceof RemoteWithExtrasException &amp;&amp; ((RemoteWithExtrasException) ioe)<a name="line.711"></a>
+<span class="sourceLineNo">712</span>              .unwrapRemoteException() instanceof NotServingRegionException)<a name="line.712"></a>
+<span class="sourceLineNo">713</span>        ) {<a name="line.713"></a>
+<span class="sourceLineNo">714</span>          // no need to retry again<a name="line.714"></a>
+<span class="sourceLineNo">715</span>          return;<a name="line.715"></a>
+<span class="sourceLineNo">716</span>        }<a name="line.716"></a>
+<span class="sourceLineNo">717</span>        LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(),<a name="line.717"></a>
+<span class="sourceLineNo">718</span>          ioe);<a name="line.718"></a>
+<span class="sourceLineNo">719</span>      }<a name="line.719"></a>
+<span class="sourceLineNo">720</span>      Thread.sleep(1000);<a name="line.720"></a>
+<span class="sourceLineNo">721</span>    }<a name="line.721"></a>
+<span class="sourceLineNo">722</span>    throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout);<a name="line.722"></a>
+<span class="sourceLineNo">723</span>  }<a name="line.723"></a>
+<span class="sourceLineNo">724</span><a name="line.724"></a>
+<span class="sourceLineNo">725</span>  /**<a name="line.725"></a>
+<span class="sourceLineNo">726</span>   * Calculate min necessary to start. This is not an absolute. It is just a friction that will<a name="line.726"></a>
+<span class="sourceLineNo">727</span>   * cause us hang around a bit longer waiting on RegionServers to check-in.<a name="line.727"></a>
+<span class="sourceLineNo">728</span>   */<a name="line.728"></a>
+<span class="sourceLineNo">729</span>  private int getMinToStart() {<a name="line.729"></a>
+<span class="sourceLineNo">730</span>    if (master.isInMaintenanceMode()) {<a name="line.730"></a>
+<span class="sourceLineNo">731</span>      // If in maintenance mode, then in process region server hosting meta will be the only server<a name="line.731"></a>
+<span class="sourceLineNo">732</span>      // available<a name="line.732"></a>
+<span class="sourceLineNo">733</span>      return 1;<a name="line.733"></a>
+<span class="sourceLineNo">734</span>    }<a name="line.734"></a>
+<span class="sourceLineNo">735</span><a name="line.735"></a>
+<span class="sourceLineNo">736</span>    int minimumRequired = 1;<a name="line.736"></a>
+<span class="sourceLineNo">737</span>    int minToStart = this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MINTOSTART, -1);<a name="line.737"></a>
+<span class="sourceLineNo">738</span>    // Ensure we are never less than minimumRequired else stuff won't work.<a name="line.738"></a>
+<span class="sourceLineNo">739</span>    return Math.max(minToStart, minimumRequired);<a name="line.739"></a>
+<span class="sourceLineNo">740</span>  }<a name="line.740"></a>
+<span class="sourceLineNo">741</span><a name="line.741"></a>
+<span class="sourceLineNo">742</span>  /**<a name="line.742"></a>
+<span class="sourceLineNo">743</span>   * Wait for the region servers to report in. We will wait until one of this condition is met: -<a name="line.743"></a>
+<span class="sourceLineNo">744</span>   * the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region<a name="line.744"></a>
+<span class="sourceLineNo">745</span>   * servers is reached - the 'hbase.master.wait.on.regionservers.mintostart' is reached AND there<a name="line.745"></a>
+<span class="sourceLineNo">746</span>   * have been no new region server in for 'hbase.master.wait.on.regionservers.interval' time AND<a name="line.746"></a>
+<span class="sourceLineNo">747</span>   * the 'hbase.master.wait.on.regionservers.timeout' is reached n<a name="line.747"></a>
+<span class="sourceLineNo">748</span>   */<a name="line.748"></a>
+<span class="sourceLineNo">749</span>  public void waitForRegionServers(MonitoredTask status) throws InterruptedException {<a name="line.749"></a>
+<span class="sourceLineNo">750</span>    final long interval =<a name="line.750"></a>
+<span class="sourceLineNo">751</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_INTERVAL, 1500);<a name="line.751"></a>
+<span class="sourceLineNo">752</span>    final long timeout =<a name="line.752"></a>
+<span class="sourceLineNo">753</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_TIMEOUT, 4500);<a name="line.753"></a>
+<span class="sourceLineNo">754</span>    // Min is not an absolute; just a friction making us wait longer on server checkin.<a name="line.754"></a>
+<span class="sourceLineNo">755</span>    int minToStart = getMinToStart();<a name="line.755"></a>
+<span class="sourceLineNo">756</span>    int maxToStart =<a name="line.756"></a>
+<span class="sourceLineNo">757</span>      this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MAXTOSTART, Integer.MAX_VALUE);<a name="line.757"></a>
+<span class="sourceLineNo">758</span>    if (maxToStart &lt; minToStart) {<a name="line.758"></a>
+<span class="sourceLineNo">759</span>      LOG.warn(String.format("The value of '%s' (%d) is set less than '%s' (%d), ignoring.",<a name="line.759"></a>
+<span class="sourceLineNo">760</span>        WAIT_ON_REGIONSERVERS_MAXTOSTART, maxToStart, WAIT_ON_REGIONSERVERS_MINTOSTART,<a name="line.760"></a>
+<span class="sourceLineNo">761</span>        minToStart));<a name="line.761"></a>
+<span class="sourceLineNo">762</span>      maxToStart = Integer.MAX_VALUE;<a name="line.762"></a>
+<span class="sourceLineNo">763</span>    }<a name="line.763"></a>
+<span class="sourceLineNo">764</span><a name="line.764"></a>
+<span class="sourceLineNo">765</span>    long now = EnvironmentEdgeManager.currentTime();<a name="line.765"></a>
+<span class="sourceLineNo">766</span>    final long startTime = now;<a name="line.766"></a>
+<span class="sourceLineNo">767</span>    long slept = 0;<a name="line.767"></a>
+<span class="sourceLineNo">768</span>    long lastLogTime = 0;<a name="line.768"></a>
+<span class="sourceLineNo">769</span>    long lastCountChange = startTime;<a name="line.769"></a>
+<span class="sourceLineNo">770</span>    int count = countOfRegionServers();<a name="line.770"></a>
+<span class="sourceLineNo">771</span>    int oldCount = 0;<a name="line.771"></a>
+<span class="sourceLineNo">772</span>    // This while test is a little hard to read. We try to comment it in below but in essence:<a name="line.772"></a>
+<span class="sourceLineNo">773</span>    // Wait if Master is not stopped and the number of regionservers that have checked-in is<a name="line.773"></a>
+<span class="sourceLineNo">774</span>    // less than the maxToStart. Both of these conditions will be true near universally.<a name="line.774"></a>
+<span class="sourceLineNo">775</span>    // Next, we will keep cycling if ANY of the following three conditions are true:<a name="line.775"></a>
+<span class="sourceLineNo">776</span>    // 1. The time since a regionserver registered is &lt; interval (means servers are actively<a name="line.776"></a>
+<span class="sourceLineNo">777</span>    // checking in).<a name="line.777"></a>
+<span class="sourceLineNo">778</span>    // 2. We are under the total timeout.<a name="line.778"></a>
+<span class="sourceLineNo">779</span>    // 3. The count of servers is &lt; minimum.<a name="line.779"></a>
+<span class="sourceLineNo">780</span>    for (ServerListener listener : this.listeners) {<a name="line.780"></a>
+<span class="sourceLineNo">781</span>      listener.waiting();<a name="line.781"></a>
+<span class="sourceLineNo">782</span>    }<a name="line.782"></a>
+<span class="sourceLineNo">783</span>    while (<a name="line.783"></a>
+<span class="sourceLineNo">784</span>      !this.master.isStopped() &amp;&amp; !isClusterShutdown() &amp;&amp; count &lt; maxToStart<a name="line.784"></a>
+<span class="sourceLineNo">785</span>        &amp;&amp; ((lastCountChange + interval) &gt; now || timeout &gt; slept || count &lt; minToStart)<a name="line.785"></a>
+<span class="sourceLineNo">786</span>    ) {<a name="line.786"></a>
+<span class="sourceLineNo">787</span>      // Log some info at every interval time or if there is a change<a name="line.787"></a>
+<span class="sourceLineNo">788</span>      if (oldCount != count || lastLogTime + interval &lt; now) {<a name="line.788"></a>
+<span class="sourceLineNo">789</span>        lastLogTime = now;<a name="line.789"></a>
+<span class="sourceLineNo">790</span>        String msg =<a name="line.790"></a>
+<span class="sourceLineNo">791</span>          "Waiting on regionserver count=" + count + "; waited=" + slept + "ms, expecting min="<a name="line.791"></a>
+<span class="sourceLineNo">792</span>            + minToStart + " server(s), max=" + getStrForMax(maxToStart) + " server(s), "<a name="line.792"></a>
+<span class="sourceLineNo">793</span>            + "timeout=" + timeout + "ms, lastChange=" + (now - lastCountChange) + "ms";<a name="line.793"></a>
+<span class="sourceLineNo">794</span>        LOG.info(msg);<a name="line.794"></a>
+<span class="sourceLineNo">795</span>        status.setStatus(msg);<a name="line.795"></a>
+<span class="sourceLineNo">796</span>      }<a name="line.796"></a>
+<span class="sourceLineNo">797</span><a name="line.797"></a>
+<span class="sourceLineNo">798</span>      // We sleep for some time<a name="line.798"></a>
+<span class="sourceLineNo">799</span>      final long sleepTime = 50;<a name="line.799"></a>
+<span class="sourceLineNo">800</span>      Thread.sleep(sleepTime);<a name="line.800"></a>
+<span class="sourceLineNo">801</span>      now = EnvironmentEdgeManager.currentTime();<a name="line.801"></a>
+<span class="sourceLineNo">802</span>      slept = now - startTime;<a name="line.802"></a>
+<span class="sourceLineNo">803</span><a name="line.803"></a>
+<span class="sourceLineNo">804</span>      oldCount = count;<a name="line.804"></a>
+<span class="sourceLineNo">805</span>      count = countOfRegionServers();<a name="line.805"></a>
+<span class="sourceLineNo">806</span>      if (count != oldCount) {<a name="line.806"></a>
+<span class="sourceLineNo">807</span>        lastCountChange = now;<a name="line.807"></a>
+<span class="sourceLineNo">808</span>      }<a name="line.808"></a>
+<span class="sourceLineNo">809</span>    }<a name="line.809"></a>
+<span class="sourceLineNo">810</span>    // Did we exit the loop because cluster is going down?<a name="line.810"></a>
+<span class="sourceLineNo">811</span>    if (isClusterShutdown()) {<a name="line.811"></a>
+<span class="sourceLineNo">812</span>      this.master.stop("Cluster shutdown");<a name="line.812"></a>
+<span class="sourceLineNo">813</span>    }<a name="line.813"></a>
+<span class="sourceLineNo">814</span>    LOG.info("Finished waiting on RegionServer count=" + count + "; waited=" + slept + "ms,"<a name="line.814"></a>
+<span class="sourceLineNo">815</span>      + " expected min=" + minToStart + " server(s), max=" + getStrForMax(maxToStart)<a name="line.815"></a>
+<span class="sourceLineNo">816</span>      + " server(s)," + " master is " + (this.master.isStopped() ? "stopped." : "running"));<a name="line.816"></a>
+<span class="sourceLineNo">817</span>  }<a name="line.817"></a>
+<span class="sourceLineNo">818</span><a name="line.818"></a>
+<span class="sourceLineNo">819</span>  private String getStrForMax(final int max) {<a name="line.819"></a>
+<span class="sourceLineNo">820</span>    return max == Integer.MAX_VALUE ? "NO_LIMIT" : Integer.toString(max);<a name="line.820"></a>
+<span class="sourceLineNo">821</span>  }<a name="line.821"></a>
+<span class="sourceLineNo">822</span><a name="line.822"></a>
+<span class="sourceLineNo">823</span>  /** Returns A copy of the internal list of online servers. */<a name="line.823"></a>
+<span class="sourceLineNo">824</span>  public List&lt;ServerName&gt; getOnlineServersList() {<a name="line.824"></a>
+<span class="sourceLineNo">825</span>    // TODO: optimize the load balancer call so we don't need to make a new list<a name="line.825"></a>
+<span class="sourceLineNo">826</span>    // TODO: FIX. THIS IS POPULAR CALL.<a name="line.826"></a>
+<span class="sourceLineNo">827</span>    return new ArrayList&lt;&gt;(this.onlineServers.keySet());<a name="line.827"></a>
+<span class="sourceLineNo">828</span>  }<a name="line.828"></a>
+<span class="sourceLineNo">829</span><a name="line.829"></a>
+<span class="sourceLineNo">830</span>  /**<a name="line.830"></a>
+<span class="sourceLineNo">831</span>   * @param keys                 The target server name<a name="line.831"></a>
+<span class="sourceLineNo">832</span>   * @param idleServerPredicator Evaluates the server on the given load<a name="line.832"></a>
+<span class="sourceLineNo">833</span>   * @return A copy of the internal list of online servers matched by the predicator<a name="line.833"></a>
+<span class="sourceLineNo">834</span>   */<a name="line.834"></a>
+<span class="sourceLineNo">835</span>  public List&lt;ServerName&gt; getOnlineServersListWithPredicator(List&lt;ServerName&gt; keys,<a name="line.835"></a>
+<span class="sourceLineNo">836</span>    Predicate&lt;ServerMetrics&gt; idleServerPredicator) {<a name="line.836"></a>
+<span class="sourceLineNo">837</span>    List&lt;ServerName&gt; names = new ArrayList&lt;&gt;();<a name="line.837"></a>
+<span class="sourceLineNo">838</span>    if (keys != null &amp;&amp; idleServerPredicator != null) {<a name="line.838"></a>
+<span class="sourceLineNo">839</span>      keys.forEach(name -&gt; {<a name="line.839"></a>
+<span class="sourceLineNo">840</span>        ServerMetrics load = onlineServers.get(name);<a name="line.840"></a>
+<span class="sourceLineNo">841</span>        if (load != null) {<a name="line.841"></a>
+<span class="sourceLineNo">842</span>          if (idleServerPredicator.test(load)) {<a name="line.842"></a>
+<span class="sourceLineNo">843</span>            names.add(name);<a name="line.843"></a>
+<span class="sourceLineNo">844</span>          }<a name="line.844"></a>
+<span class="sourceLineNo">845</span>        }<a name="line.845"></a>
+<span class="sourceLineNo">846</span>      });<a name="line.846"></a>
+<span class="sourceLineNo">847</span>    }<a name="line.847"></a>
+<span class="sourceLineNo">848</span>    return names;<a name="line.848"></a>
 <span class="sourceLineNo">849</span>  }<a name="line.849"></a>
 <span class="sourceLineNo">850</span><a name="line.850"></a>
-<span class="sourceLineNo">851</span>  public boolean isServerOnline(ServerName serverName) {<a name="line.851"></a>
-<span class="sourceLineNo">852</span>    return serverName != null &amp;&amp; onlineServers.containsKey(serverName);<a name="line.852"></a>
-<span class="sourceLineNo">853</span>  }<a name="line.853"></a>
-<span class="sourceLineNo">854</span><a name="line.854"></a>
-<span class="sourceLineNo">855</span>  public enum ServerLiveState {<a name="line.855"></a>
-<span class="sourceLineNo">856</span>    LIVE,<a name="line.856"></a>
-<span class="sourceLineNo">857</span>    DEAD,<a name="line.857"></a>
-<span class="sourceLineNo">858</span>    UNKNOWN<a name="line.858"></a>
-<span class="sourceLineNo">859</span>  }<a name="line.859"></a>
-<span class="sourceLineNo">860</span><a name="line.860"></a>
-<span class="sourceLineNo">861</span>  /** Returns whether the server is online, dead, or unknown. */<a name="line.861"></a>
-<span class="sourceLineNo">862</span>  public synchronized ServerLiveState isServerKnownAndOnline(ServerName serverName) {<a name="line.862"></a>
-<span class="sourceLineNo">863</span>    return onlineServers.containsKey(serverName)<a name="line.863"></a>
-<span class="sourceLineNo">864</span>      ? ServerLiveState.LIVE<a name="line.864"></a>
-<span class="sourceLineNo">865</span>      : (deadservers.isDeadServer(serverName) ? ServerLiveState.DEAD : ServerLiveState.UNKNOWN);<a name="line.865"></a>
-<span class="sourceLineNo">866</span>  }<a name="line.866"></a>
-<span class="sourceLineNo">867</span><a name="line.867"></a>
-<span class="sourceLineNo">868</span>  /**<a name="line.868"></a>
-<span class="sourceLineNo">869</span>   * Check if a server is known to be dead. A server can be online, or known to be dead, or unknown<a name="line.869"></a>
-<span class="sourceLineNo">870</span>   * to this manager (i.e, not online, not known to be dead either; it is simply not tracked by the<a name="line.870"></a>
-<span class="sourceLineNo">871</span>   * master any more, for example, a very old previous instance).<a name="line.871"></a>
-<span class="sourceLineNo">872</span>   */<a name="line.872"></a>
-<span class="sourceLineNo">873</span>  public synchronized boolean isServerDead(ServerName serverName) {<a name="line.873"></a>
-<span class="sourceLineNo">874</span>    return serverName == null || deadservers.isDeadServer(serverName);<a name="line.874"></a>
-<span class="sourceLineNo">875</span>  }<a name="line.875"></a>
-<span class="sourceLineNo">876</span><a name="line.876"></a>
-<span class="sourceLineNo">877</span>  /**<a name="line.877"></a>
-<span class="sourceLineNo">878</span>   * Check if a server is unknown. A server can be online, or known to be dead, or unknown to this<a name="line.878"></a>
-<span class="sourceLineNo">879</span>   * manager (i.e, not online, not known to be dead either; it is simply not tracked by the master<a name="line.879"></a>
-<span class="sourceLineNo">880</span>   * any more, for example, a very old previous instance).<a name="line.880"></a>
-<span class="sourceLineNo">881</span>   */<a name="line.881"></a>
-<span class="sourceLineNo">882</span>  public boolean isServerUnknown(ServerName serverName) {<a name="line.882"></a>
-<span class="sourceLineNo">883</span>    return serverName == null<a name="line.883"></a>
-<span class="sourceLineNo">884</span>      || (!onlineServers.containsKey(serverName) &amp;&amp; !deadservers.isDeadServer(serverName));<a name="line.884"></a>
-<span class="sourceLineNo">885</span>  }<a name="line.885"></a>
-<span class="sourceLineNo">886</span><a name="line.886"></a>
-<span class="sourceLineNo">887</span>  public void shutdownCluster() {<a name="line.887"></a>
-<span class="sourceLineNo">888</span>    String statusStr = "Cluster shutdown requested of master=" + this.master.getServerName();<a name="line.888"></a>
-<span class="sourceLineNo">889</span>    LOG.info(statusStr);<a name="line.889"></a>
-<span class="sourceLineNo">890</span>    this.clusterShutdown.set(true);<a name="line.890"></a>
-<span class="sourceLineNo">891</span>    if (onlineServers.isEmpty()) {<a name="line.891"></a>
-<span class="sourceLineNo">892</span>      // we do not synchronize here so this may cause a double stop, but not a big deal<a name="line.892"></a>
-<span class="sourceLineNo">893</span>      master.stop("OnlineServer=0 right after cluster shutdown set");<a name="line.893"></a>
-<span class="sourceLineNo">894</span>    }<a name="line.894"></a>
-<span class="sourceLineNo">895</span>  }<a name="line.895"></a>
-<span class="sourceLineNo">896</span><a name="line.896"></a>
-<span class="sourceLineNo">897</span>  public boolean isClusterShutdown() {<a name="line.897"></a>
-<span class="sourceLineNo">898</span>    return this.clusterShutdown.get();<a name="line.898"></a>
-<span class="sourceLineNo">899</span>  }<a name="line.899"></a>
-<span class="sourceLineNo">900</span><a name="line.900"></a>
-<span class="sourceLineNo">901</span>  /**<a name="line.901"></a>
-<span class="sourceLineNo">902</span>   * start chore in ServerManager<a name="line.902"></a>
-<span class="sourceLineNo">903</span>   */<a name="line.903"></a>
-<span class="sourceLineNo">904</span>  public void startChore() {<a name="line.904"></a>
-<span class="sourceLineNo">905</span>    Configuration c = master.getConfiguration();<a name="line.905"></a>
-<span class="sourceLineNo">906</span>    if (persistFlushedSequenceId) {<a name="line.906"></a>
-<span class="sourceLineNo">907</span>      new Thread(() -&gt; {<a name="line.907"></a>
-<span class="sourceLineNo">908</span>        // after AM#loadMeta, RegionStates should be loaded, and some regions are<a name="line.908"></a>
-<span class="sourceLineNo">909</span>        // deleted by drop/split/merge during removeDeletedRegionFromLoadedFlushedSequenceIds,<a name="line.909"></a>
-<span class="sourceLineNo">910</span>        // but these deleted regions are not added back to RegionStates,<a name="line.910"></a>
-<span class="sourceLineNo">911</span>        // so we can safely remove deleted regions.<a name="line.911"></a>
-<span class="sourceLineNo">912</span>        removeDeletedRegionFromLoadedFlushedSequenceIds();<a name="line.912"></a>
-<span class="sourceLineNo">913</span>      }, "RemoveDeletedRegionSyncThread").start();<a name="line.913"></a>
-<span class="sourceLineNo">914</span>      int flushPeriod =<a name="line.914"></a>
-<span class="sourceLineNo">915</span>        c.getInt(FLUSHEDSEQUENCEID_FLUSHER_INTERVAL, FLUSHEDSEQUENCEID_FLUSHER_INTERVAL_DEFAULT);<a name="line.915"></a>
-<span class="sourceLineNo">916</span>      flushedSeqIdFlusher = new FlushedSequenceIdFlusher("FlushedSequenceIdFlusher", flushPeriod);<a name="line.916"></a>
-<span class="sourceLineNo">917</span>      master.getChoreService().scheduleChore(flushedSeqIdFlusher);<a name="line.917"></a>
-<span class="sourceLineNo">918</span>    }<a name="line.918"></a>
-<span class="sourceLineNo">919</span>  }<a name="line.919"></a>
-<span class="sourceLineNo">920</span><a name="line.920"></a>
-<span class="sourceLineNo">921</span>  /**<a name="line.921"></a>
-<span class="sourceLineNo">922</span>   * Stop the ServerManager.<a name="line.922"></a>
-<span class="sourceLineNo">923</span>   */<a name="line.923"></a>
-<span class="sourceLineNo">924</span>  public void stop() {<a name="line.924"></a>
-<span class="sourceLineNo">925</span>    if (flushedSeqIdFlusher != null) {<a name="line.925"></a>
-<span class="sourceLineNo">926</span>      flushedSeqIdFlusher.shutdown();<a name="line.926"></a>
-<span class="sourceLineNo">927</span>    }<a name="line.927"></a>
-<span class="sourceLineNo">928</span>    if (persistFlushedSequenceId) {<a name="line.928"></a>
-<span class="sourceLineNo">929</span>      try {<a name="line.929"></a>
-<span class="sourceLineNo">930</span>        persistRegionLastFlushedSequenceIds();<a name="line.930"></a>
-<span class="sourceLineNo">931</span>      } catch (IOException e) {<a name="line.931"></a>
-<span class="sourceLineNo">932</span>        LOG.warn("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.932"></a>
-<span class="sourceLineNo">933</span>      }<a name="line.933"></a>
-<span class="sourceLineNo">934</span>    }<a name="line.934"></a>
-<span class="sourceLineNo">935</span>  }<a name="line.935"></a>
-<span class="sourceLineNo">936</span><a name="line.936"></a>
-<span class="sourceLineNo">937</span>  /**<a name="line.937"></a>
-<span class="sourceLineNo">938</span>   * Creates a list of possible destinations for a region. It contains the online servers, but not<a name="line.938"></a>
-<span class="sourceLineNo">939</span>   * the draining or dying servers.<a name="line.939"></a>
-<span class="sourceLineNo">940</span>   * @param serversToExclude can be null if there is no server to exclude<a name="line.940"></a>
-<span class="sourceLineNo">941</span>   */<a name="line.941"></a>
-<span class="sourceLineNo">942</span>  public List&lt;ServerName&gt; createDestinationServersList(final List&lt;ServerName&gt; serversToExclude) {<a name="line.942"></a>
-<span class="sourceLineNo">943</span>    Set&lt;ServerName&gt; destServers = new HashSet&lt;&gt;();<a name="line.943"></a>
-<span class="sourceLineNo">944</span>    onlineServers.forEach((sn, sm) -&gt; {<a name="line.944"></a>
-<span class="sourceLineNo">945</span>      if (sm.getLastReportTimestamp() &gt; 0) {<a name="line.945"></a>
-<span class="sourceLineNo">946</span>        // This means we have already called regionServerReport at leaset once, then let's include<a name="line.946"></a>
-<span class="sourceLineNo">947</span>        // this server for region assignment. This is an optimization to avoid assigning regions to<a name="line.947"></a>
-<span class="sourceLineNo">948</span>        // an uninitialized server. See HBASE-25032 for more details.<a name="line.948"></a>
-<span class="sourceLineNo">949</span>        destServers.add(sn);<a name="line.949"></a>
-<span class="sourceLineNo">950</span>      }<a name="line.950"></a>
-<span class="sourceLineNo">951</span>    });<a name="line.951"></a>
-<span class="sourceLineNo">952</span><a name="line.952"></a>
-<span class="sourceLineNo">953</span>    if (serversToExclude != null) {<a name="line.953"></a>
-<span class="sourceLineNo">954</span>      destServers.removeAll(serversToExclude);<a name="line.954"></a>
-<span class="sourceLineNo">955</span>    }<a name="line.955"></a>
-<span class="sourceLineNo">956</span><a name="line.956"></a>
-<span class="sourceLineNo">957</span>    // Loop through the draining server list and remove them from the server list<a name="line.957"></a>
-<span class="sourceLineNo">958</span>    final List&lt;ServerName&gt; drainingServersCopy = getDrainingServersList();<a name="line.958"></a>
-<span class="sourceLineNo">959</span>    destServers.removeAll(drainingServersCopy);<a name="line.959"></a>
-<span class="sourceLineNo">960</span><a name="line.960"></a>
-<span class="sourceLineNo">961</span>    return new ArrayList&lt;&gt;(destServers);<a name="line.961"></a>
-<span class="sourceLineNo">962</span>  }<a name="line.962"></a>
-<span class="sourceLineNo">963</span><a name="line.963"></a>
-<span class="sourceLineNo">964</span>  /**<a name="line.964"></a>
-<span class="sourceLineNo">965</span>   * Calls {@link #createDestinationServersList} without server to exclude.<a name="line.965"></a>
-<span class="sourceLineNo">966</span>   */<a name="line.966"></a>
-<span class="sourceLineNo">967</span>  public List&lt;ServerName&gt; createDestinationServersList() {<a name="line.967"></a>
-<span class="sourceLineNo">968</span>    return createDestinationServersList(null);<a name="line.968"></a>
-<span class="sourceLineNo">969</span>  }<a name="line.969"></a>
-<span class="sourceLineNo">970</span><a name="line.970"></a>
-<span class="sourceLineNo">971</span>  /**<a name="line.971"></a>
-<span class="sourceLineNo">972</span>   * To clear any dead server with same host name and port of any online server<a name="line.972"></a>
-<span class="sourceLineNo">973</span>   */<a name="line.973"></a>
-<span class="sourceLineNo">974</span>  void clearDeadServersWithSameHostNameAndPortOfOnlineServer() {<a name="line.974"></a>
-<span class="sourceLineNo">975</span>    for (ServerName serverName : getOnlineServersList()) {<a name="line.975"></a>
-<span class="sourceLineNo">976</span>      deadservers.cleanAllPreviousInstances(serverName);<a name="line.976"></a>
-<span class="sourceLineNo">977</span>    }<a name="line.977"></a>
-<span class="sourceLineNo">978</span>  }<a name="line.978"></a>
-<span class="sourceLineNo">979</span><a name="line.979"></a>
-<span class="sourceLineNo">980</span>  /**<a name="line.980"></a>
-<span class="sourceLineNo">981</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.981"></a>
-<span class="sourceLineNo">982</span>   */<a name="line.982"></a>
-<span class="sourceLineNo">983</span>  public void removeRegion(final RegionInfo regionInfo) {<a name="line.983"></a>
-<span class="sourceLineNo">984</span>    final byte[] encodedName = regionInfo.getEncodedNameAsBytes();<a name="line.984"></a>
-<span class="sourceLineNo">985</span>    storeFlushedSequenceIdsByRegion.remove(encodedName);<a name="line.985"></a>
-<span class="sourceLineNo">986</span>    flushedSequenceIdByRegion.remove(encodedName);<a name="line.986"></a>
-<span class="sourceLineNo">987</span>  }<a name="line.987"></a>
-<span class="sourceLineNo">988</span><a name="line.988"></a>
-<span class="sourceLineNo">989</span>  public boolean isRegionInServerManagerStates(final RegionInfo hri) {<a name="line.989"></a>
-<span class="sourceLineNo">990</span>    final byte[] encodedName = hri.getEncodedNameAsBytes();<a name="line.990"></a>
-<span class="sourceLineNo">991</span>    return (storeFlushedSequenceIdsByRegion.containsKey(encodedName)<a name="line.991"></a>
-<span class="sourceLineNo">992</span>      || flushedSequenceIdByRegion.containsKey(encodedName));<a name="line.992"></a>
-<span class="sourceLineNo">993</span>  }<a name="line.993"></a>
-<span class="sourceLineNo">994</span><a name="line.994"></a>
-<span class="sourceLineNo">995</span>  /**<a name="line.995"></a>
-<span class="sourceLineNo">996</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.996"></a>
-<span class="sourceLineNo">997</span>   */<a name="line.997"></a>
-<span class="sourceLineNo">998</span>  public void removeRegions(final List&lt;RegionInfo&gt; regions) {<a name="line.998"></a>
-<span class="sourceLineNo">999</span>    for (RegionInfo hri : regions) {<a name="line.999"></a>
-<span class="sourceLineNo">1000</span>      removeRegion(hri);<a name="line.1000"></a>
-<span class="sourceLineNo">1001</span>    }<a name="line.1001"></a>
-<span class="sourceLineNo">1002</span>  }<a name="line.1002"></a>
-<span class="sourceLineNo">1003</span><a name="line.1003"></a>
-<span class="sourceLineNo">1004</span>  /**<a name="line.1004"></a>
-<span class="sourceLineNo">1005</span>   * May return 0 when server is not online.<a name="line.1005"></a>
-<span class="sourceLineNo">1006</span>   */<a name="line.1006"></a>
-<span class="sourceLineNo">1007</span>  public int getVersionNumber(ServerName serverName) {<a name="line.1007"></a>
-<span class="sourceLineNo">1008</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1008"></a>
-<span class="sourceLineNo">1009</span>    return serverMetrics != null ? serverMetrics.getVersionNumber() : 0;<a name="line.1009"></a>
-<span class="sourceLineNo">1010</span>  }<a name="line.1010"></a>
-<span class="sourceLineNo">1011</span><a name="line.1011"></a>
-<span class="sourceLineNo">1012</span>  /**<a name="line.1012"></a>
-<span class="sourceLineNo">1013</span>   * May return "0.0.0" when server is not online<a name="line.1013"></a>
-<span class="sourceLineNo">1014</span>   */<a name="line.1014"></a>
-<span class="sourceLineNo">1015</span>  public String getVersion(ServerName serverName) {<a name="line.1015"></a>
-<span class="sourceLineNo">1016</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1016"></a>
-<span class="sourceLineNo">1017</span>    return serverMetrics != null ? serverMetrics.getVersion() : "0.0.0";<a name="line.1017"></a>
-<span class="sourceLineNo">1018</span>  }<a name="line.1018"></a>
-<span class="sourceLineNo">1019</span><a name="line.1019"></a>
-<span class="sourceLineNo">1020</span>  public int getInfoPort(ServerName serverName) {<a name="line.1020"></a>
+<span class="sourceLineNo">851</span>  /** Returns A copy of the internal list of draining servers. */<a name="line.851"></a>
+<span class="sourceLineNo">852</span>  public List&lt;ServerName&gt; getDrainingServersList() {<a name="line.852"></a>
+<span class="sourceLineNo">853</span>    return new ArrayList&lt;&gt;(this.drainingServers);<a name="line.853"></a>
+<span class="sourceLineNo">854</span>  }<a name="line.854"></a>
+<span class="sourceLineNo">855</span><a name="line.855"></a>
+<span class="sourceLineNo">856</span>  public boolean isServerOnline(ServerName serverName) {<a name="line.856"></a>
+<span class="sourceLineNo">857</span>    return serverName != null &amp;&amp; onlineServers.containsKey(serverName);<a name="line.857"></a>
+<span class="sourceLineNo">858</span>  }<a name="line.858"></a>
+<span class="sourceLineNo">859</span><a name="line.859"></a>
+<span class="sourceLineNo">860</span>  public enum ServerLiveState {<a name="line.860"></a>
+<span class="sourceLineNo">861</span>    LIVE,<a name="line.861"></a>
+<span class="sourceLineNo">862</span>    DEAD,<a name="line.862"></a>
+<span class="sourceLineNo">863</span>    UNKNOWN<a name="line.863"></a>
+<span class="sourceLineNo">864</span>  }<a name="line.864"></a>
+<span class="sourceLineNo">865</span><a name="line.865"></a>
+<span class="sourceLineNo">866</span>  /** Returns whether the server is online, dead, or unknown. */<a name="line.866"></a>
+<span class="sourceLineNo">867</span>  public synchronized ServerLiveState isServerKnownAndOnline(ServerName serverName) {<a name="line.867"></a>
+<span class="sourceLineNo">868</span>    return onlineServers.containsKey(serverName)<a name="line.868"></a>
+<span class="sourceLineNo">869</span>      ? ServerLiveState.LIVE<a name="line.869"></a>
+<span class="sourceLineNo">870</span>      : (deadservers.isDeadServer(serverName) ? ServerLiveState.DEAD : ServerLiveState.UNKNOWN);<a name="line.870"></a>
+<span class="sourceLineNo">871</span>  }<a name="line.871"></a>
+<span class="sourceLineNo">872</span><a name="line.872"></a>
+<span class="sourceLineNo">873</span>  /**<a name="line.873"></a>
+<span class="sourceLineNo">874</span>   * Check if a server is known to be dead. A server can be online, or known to be dead, or unknown<a name="line.874"></a>
+<span class="sourceLineNo">875</span>   * to this manager (i.e, not online, not known to be dead either; it is simply not tracked by the<a name="line.875"></a>
+<span class="sourceLineNo">876</span>   * master any more, for example, a very old previous instance).<a name="line.876"></a>
+<span class="sourceLineNo">877</span>   */<a name="line.877"></a>
+<span class="sourceLineNo">878</span>  public synchronized boolean isServerDead(ServerName serverName) {<a name="line.878"></a>
+<span class="sourceLineNo">879</span>    return serverName == null || deadservers.isDeadServer(serverName);<a name="line.879"></a>
+<span class="sourceLineNo">880</span>  }<a name="line.880"></a>
+<span class="sourceLineNo">881</span><a name="line.881"></a>
+<span class="sourceLineNo">882</span>  /**<a name="line.882"></a>
+<span class="sourceLineNo">883</span>   * Check if a server is unknown. A server can be online, or known to be dead, or unknown to this<a name="line.883"></a>
+<span class="sourceLineNo">884</span>   * manager (i.e, not online, not known to be dead either; it is simply not tracked by the master<a name="line.884"></a>
+<span class="sourceLineNo">885</span>   * any more, for example, a very old previous instance).<a name="line.885"></a>
+<span class="sourceLineNo">886</span>   */<a name="line.886"></a>
+<span class="sourceLineNo">887</span>  public boolean isServerUnknown(ServerName serverName) {<a name="line.887"></a>
+<span class="sourceLineNo">888</span>    return serverName == null<a name="line.888"></a>
+<span class="sourceLineNo">889</span>      || (!onlineServers.containsKey(serverName) &amp;&amp; !deadservers.isDeadServer(serverName));<a name="line.889"></a>
+<span class="sourceLineNo">890</span>  }<a name="line.890"></a>
+<span class="sourceLineNo">891</span><a name="line.891"></a>
+<span class="sourceLineNo">892</span>  public void shutdownCluster() {<a name="line.892"></a>
+<span class="sourceLineNo">893</span>    String statusStr = "Cluster shutdown requested of master=" + this.master.getServerName();<a name="line.893"></a>
+<span class="sourceLineNo">894</span>    LOG.info(statusStr);<a name="line.894"></a>
+<span class="sourceLineNo">895</span>    this.clusterShutdown.set(true);<a name="line.895"></a>
+<span class="sourceLineNo">896</span>    if (onlineServers.isEmpty()) {<a name="line.896"></a>
+<span class="sourceLineNo">897</span>      // we do not synchronize here so this may cause a double stop, but not a big deal<a name="line.897"></a>
+<span class="sourceLineNo">898</span>      master.stop("OnlineServer=0 right after cluster shutdown set");<a name="line.898"></a>
+<span class="sourceLineNo">899</span>    }<a name="line.899"></a>
+<span class="sourceLineNo">900</span>  }<a name="line.900"></a>
+<span class="sourceLineNo">901</span><a name="line.901"></a>
+<span class="sourceLineNo">902</span>  public boolean isClusterShutdown() {<a name="line.902"></a>
+<span class="sourceLineNo">903</span>    return this.clusterShutdown.get();<a name="line.903"></a>
+<span class="sourceLineNo">904</span>  }<a name="line.904"></a>
+<span class="sourceLineNo">905</span><a name="line.905"></a>
+<span class="sourceLineNo">906</span>  /**<a name="line.906"></a>
+<span class="sourceLineNo">907</span>   * start chore in ServerManager<a name="line.907"></a>
+<span class="sourceLineNo">908</span>   */<a name="line.908"></a>
+<span class="sourceLineNo">909</span>  public void startChore() {<a name="line.909"></a>
+<span class="sourceLineNo">910</span>    Configuration c = master.getConfiguration();<a name="line.910"></a>
+<span class="sourceLineNo">911</span>    if (persistFlushedSequenceId) {<a name="line.911"></a>
+<span class="sourceLineNo">912</span>      new Thread(() -&gt; {<a name="line.912"></a>
+<span class="sourceLineNo">913</span>        // after AM#loadMeta, RegionStates should be loaded, and some regions are<a name="line.913"></a>
+<span class="sourceLineNo">914</span>        // deleted by drop/split/merge during removeDeletedRegionFromLoadedFlushedSequenceIds,<a name="line.914"></a>
+<span class="sourceLineNo">915</span>        // but these deleted regions are not added back to RegionStates,<a name="line.915"></a>
+<span class="sourceLineNo">916</span>        // so we can safely remove deleted regions.<a name="line.916"></a>
+<span class="sourceLineNo">917</span>        removeDeletedRegionFromLoadedFlushedSequenceIds();<a name="line.917"></a>
+<span class="sourceLineNo">918</span>      }, "RemoveDeletedRegionSyncThread").start();<a name="line.918"></a>
+<span class="sourceLineNo">919</span>      int flushPeriod =<a name="line.919"></a>
+<span class="sourceLineNo">920</span>        c.getInt(FLUSHEDSEQUENCEID_FLUSHER_INTERVAL, FLUSHEDSEQUENCEID_FLUSHER_INTERVAL_DEFAULT);<a name="line.920"></a>
+<span class="sourceLineNo">921</span>      flushedSeqIdFlusher = new FlushedSequenceIdFlusher("FlushedSequenceIdFlusher", flushPeriod);<a name="line.921"></a>
+<span class="sourceLineNo">922</span>      master.getChoreService().scheduleChore(flushedSeqIdFlusher);<a name="line.922"></a>
+<span class="sourceLineNo">923</span>    }<a name="line.923"></a>
+<span class="sourceLineNo">924</span>  }<a name="line.924"></a>
+<span class="sourceLineNo">925</span><a name="line.925"></a>
+<span class="sourceLineNo">926</span>  /**<a name="line.926"></a>
+<span class="sourceLineNo">927</span>   * Stop the ServerManager.<a name="line.927"></a>
+<span class="sourceLineNo">928</span>   */<a name="line.928"></a>
+<span class="sourceLineNo">929</span>  public void stop() {<a name="line.929"></a>
+<span class="sourceLineNo">930</span>    if (flushedSeqIdFlusher != null) {<a name="line.930"></a>
+<span class="sourceLineNo">931</span>      flushedSeqIdFlusher.shutdown();<a name="line.931"></a>
+<span class="sourceLineNo">932</span>    }<a name="line.932"></a>
+<span class="sourceLineNo">933</span>    if (persistFlushedSequenceId) {<a name="line.933"></a>
+<span class="sourceLineNo">934</span>      try {<a name="line.934"></a>
+<span class="sourceLineNo">935</span>        persistRegionLastFlushedSequenceIds();<a name="line.935"></a>
+<span class="sourceLineNo">936</span>      } catch (IOException e) {<a name="line.936"></a>
+<span class="sourceLineNo">937</span>        LOG.warn("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.937"></a>
+<span class="sourceLineNo">938</span>      }<a name="line.938"></a>
+<span class="sourceLineNo">939</span>    }<a name="line.939"></a>
+<span class="sourceLineNo">940</span>  }<a name="line.940"></a>
+<span class="sourceLineNo">941</span><a name="line.941"></a>
+<span class="sourceLineNo">942</span>  /**<a name="line.942"></a>
+<span class="sourceLineNo">943</span>   * Creates a list of possible destinations for a region. It contains the online servers, but not<a name="line.943"></a>
+<span class="sourceLineNo">944</span>   * the draining or dying servers.<a name="line.944"></a>
+<span class="sourceLineNo">945</span>   * @param serversToExclude can be null if there is no server to exclude<a name="line.945"></a>
+<span class="sourceLineNo">946</span>   */<a name="line.946"></a>
+<span class="sourceLineNo">947</span>  public List&lt;ServerName&gt; createDestinationServersList(final List&lt;ServerName&gt; serversToExclude) {<a name="line.947"></a>
+<span class="sourceLineNo">948</span>    Set&lt;ServerName&gt; destServers = new HashSet&lt;&gt;();<a name="line.948"></a>
+<span class="sourceLineNo">949</span>    onlineServers.forEach((sn, sm) -&gt; {<a name="line.949"></a>
+<span class="sourceLineNo">950</span>      if (sm.getLastReportTimestamp() &gt; 0) {<a name="line.950"></a>
+<span class="sourceLineNo">951</span>        // This means we have already called regionServerReport at leaset once, then let's include<a name="line.951"></a>
+<span class="sourceLineNo">952</span>        // this server for region assignment. This is an optimization to avoid assigning regions to<a name="line.952"></a>
+<span class="sourceLineNo">953</span>        // an uninitialized server. See HBASE-25032 for more details.<a name="line.953"></a>
+<span class="sourceLineNo">954</span>        destServers.add(sn);<a name="line.954"></a>
+<span class="sourceLineNo">955</span>      }<a name="line.955"></a>
+<span class="sourceLineNo">956</span>    });<a name="line.956"></a>
+<span class="sourceLineNo">957</span><a name="line.957"></a>
+<span class="sourceLineNo">958</span>    if (serversToExclude != null) {<a name="line.958"></a>
+<span class="sourceLineNo">959</span>      destServers.removeAll(serversToExclude);<a name="line.959"></a>
+<span class="sourceLineNo">960</span>    }<a name="line.960"></a>
+<span class="sourceLineNo">961</span><a name="line.961"></a>
+<span class="sourceLineNo">962</span>    // Loop through the draining server list and remove them from the server list<a name="line.962"></a>
+<span class="sourceLineNo">963</span>    final List&lt;ServerName&gt; drainingServersCopy = getDrainingServersList();<a name="line.963"></a>
+<span class="sourceLineNo">964</span>    destServers.removeAll(drainingServersCopy);<a name="line.964"></a>
+<span class="sourceLineNo">965</span><a name="line.965"></a>
+<span class="sourceLineNo">966</span>    return new ArrayList&lt;&gt;(destServers);<a name="line.966"></a>
+<span class="sourceLineNo">967</span>  }<a name="line.967"></a>
+<span class="sourceLineNo">968</span><a name="line.968"></a>
+<span class="sourceLineNo">969</span>  /**<a name="line.969"></a>
+<span class="sourceLineNo">970</span>   * Calls {@link #createDestinationServersList} without server to exclude.<a name="line.970"></a>
+<span class="sourceLineNo">971</span>   */<a name="line.971"></a>
+<span class="sourceLineNo">972</span>  public List&lt;ServerName&gt; createDestinationServersList() {<a name="line.972"></a>
+<span class="sourceLineNo">973</span>    return createDestinationServersList(null);<a name="line.973"></a>
+<span class="sourceLineNo">974</span>  }<a name="line.974"></a>
+<span class="sourceLineNo">975</span><a name="line.975"></a>
+<span class="sourceLineNo">976</span>  /**<a name="line.976"></a>
+<span class="sourceLineNo">977</span>   * To clear any dead server with same host name and port of any online server<a name="line.977"></a>
+<span class="sourceLineNo">978</span>   */<a name="line.978"></a>
+<span class="sourceLineNo">979</span>  void clearDeadServersWithSameHostNameAndPortOfOnlineServer() {<a name="line.979"></a>
+<span class="sourceLineNo">980</span>    for (ServerName serverName : getOnlineServersList()) {<a name="line.980"></a>
+<span class="sourceLineNo">981</span>      deadservers.cleanAllPreviousInstances(serverName);<a name="line.981"></a>
+<span class="sourceLineNo">982</span>    }<a name="line.982"></a>
+<span class="sourceLineNo">983</span>  }<a name="line.983"></a>
+<span class="sourceLineNo">984</span><a name="line.984"></a>
+<span class="sourceLineNo">985</span>  /**<a name="line.985"></a>
+<span class="sourceLineNo">986</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.986"></a>
+<span class="sourceLineNo">987</span>   */<a name="line.987"></a>
+<span class="sourceLineNo">988</span>  public void removeRegion(final RegionInfo regionInfo) {<a name="line.988"></a>
+<span class="sourceLineNo">989</span>    final byte[] encodedName = regionInfo.getEncodedNameAsBytes();<a name="line.989"></a>
+<span class="sourceLineNo">990</span>    storeFlushedSequenceIdsByRegion.remove(encodedName);<a name="line.990"></a>
+<span class="sourceLineNo">991</span>    flushedSequenceIdByRegion.remove(encodedName);<a name="line.991"></a>
+<span class="sourceLineNo">992</span>  }<a name="line.992"></a>
+<span class="sourceLineNo">993</span><a name="line.993"></a>
+<span class="sourceLineNo">994</span>  public boolean isRegionInServerManagerStates(final RegionInfo hri) {<a name="line.994"></a>
+<span class="sourceLineNo">995</span>    final byte[] encodedName = hri.getEncodedNameAsBytes();<a name="line.995"></a>
+<span class="sourceLineNo">996</span>    return (storeFlushedSequenceIdsByRegion.containsKey(encodedName)<a name="line.996"></a>
+<span class="sourceLineNo">997</span>      || flushedSequenceIdByRegion.containsKey(encodedName));<a name="line.997"></a>
+<span class="sourceLineNo">998</span>  }<a name="line.998"></a>
+<span class="sourceLineNo">999</span><a name="line.999"></a>
+<span class="sourceLineNo">1000</span>  /**<a name="line.1000"></a>
+<span class="sourceLineNo">1001</span>   * Called by delete table and similar to notify the ServerManager that a region was removed.<a name="line.1001"></a>
+<span class="sourceLineNo">1002</span>   */<a name="line.1002"></a>
+<span class="sourceLineNo">1003</span>  public void removeRegions(final List&lt;RegionInfo&gt; regions) {<a name="line.1003"></a>
+<span class="sourceLineNo">1004</span>    for (RegionInfo hri : regions) {<a name="line.1004"></a>
+<span class="sourceLineNo">1005</span>      removeRegion(hri);<a name="line.1005"></a>
+<span class="sourceLineNo">1006</span>    }<a name="line.1006"></a>
+<span class="sourceLineNo">1007</span>  }<a name="line.1007"></a>
+<span class="sourceLineNo">1008</span><a name="line.1008"></a>
+<span class="sourceLineNo">1009</span>  /**<a name="line.1009"></a>
+<span class="sourceLineNo">1010</span>   * May return 0 when server is not online.<a name="line.1010"></a>
+<span class="sourceLineNo">1011</span>   */<a name="line.1011"></a>
+<span class="sourceLineNo">1012</span>  public int getVersionNumber(ServerName serverName) {<a name="line.1012"></a>
+<span class="sourceLineNo">1013</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1013"></a>
+<span class="sourceLineNo">1014</span>    return serverMetrics != null ? serverMetrics.getVersionNumber() : 0;<a name="line.1014"></a>
+<span class="sourceLineNo">1015</span>  }<a name="line.1015"></a>
+<span class="sourceLineNo">1016</span><a name="line.1016"></a>
+<span class="sourceLineNo">1017</span>  /**<a name="line.1017"></a>
+<span class="sourceLineNo">1018</span>   * May return "0.0.0" when server is not online<a name="line.1018"></a>
+<span class="sourceLineNo">1019</span>   */<a name="line.1019"></a>
+<span class="sourceLineNo">1020</span>  public String getVersion(ServerName serverName) {<a name="line.1020"></a>
 <span class="sourceLineNo">1021</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1021"></a>
-<span class="sourceLineNo">1022</span>    return serverMetrics != null ? serverMetrics.getInfoServerPort() : 0;<a name="line.1022"></a>
+<span class="sourceLineNo">1022</span>    return serverMetrics != null ? serverMetrics.getVersion() : "0.0.0";<a name="line.1022"></a>
 <span class="sourceLineNo">1023</span>  }<a name="line.1023"></a>
 <span class="sourceLineNo">1024</span><a name="line.1024"></a>
-<span class="sourceLineNo">1025</span>  /**<a name="line.1025"></a>
-<span class="sourceLineNo">1026</span>   * Persist last flushed sequence id of each region to HDFS<a name="line.1026"></a>
-<span class="sourceLineNo">1027</span>   * @throws IOException if persit to HDFS fails<a name="line.1027"></a>
-<span class="sourceLineNo">1028</span>   */<a name="line.1028"></a>
-<span class="sourceLineNo">1029</span>  private void persistRegionLastFlushedSequenceIds() throws IOException {<a name="line.1029"></a>
-<span class="sourceLineNo">1030</span>    if (isFlushSeqIdPersistInProgress) {<a name="line.1030"></a>
-<span class="sourceLineNo">1031</span>      return;<a name="line.1031"></a>
-<span class="sourceLineNo">1032</span>    }<a name="line.1032"></a>
-<span class="sourceLineNo">1033</span>    isFlushSeqIdPersistInProgress = true;<a name="line.1033"></a>
-<span class="sourceLineNo">1034</span>    try {<a name="line.1034"></a>
-<span class="sourceLineNo">1035</span>      Configuration conf = master.getConfiguration();<a name="line.1035"></a>
-<span class="sourceLineNo">1036</span>      Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1036"></a>
-<span class="sourceLineNo">1037</span>      Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1037"></a>
-<span class="sourceLineNo">1038</span>      FileSystem fs = FileSystem.get(conf);<a name="line.1038"></a>
-<span class="sourceLineNo">1039</span>      if (fs.exists(lastFlushedSeqIdPath)) {<a name="line.1039"></a>
-<span class="sourceLineNo">1040</span>        LOG.info("Rewriting .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1040"></a>
-<span class="sourceLineNo">1041</span>        if (!fs.delete(lastFlushedSeqIdPath, false)) {<a name="line.1041"></a>
-<span class="sourceLineNo">1042</span>          throw new IOException("Unable to remove existing " + lastFlushedSeqIdPath);<a name="line.1042"></a>
-<span class="sourceLineNo">1043</span>        }<a name="line.1043"></a>
-<span class="sourceLineNo">1044</span>      } else {<a name="line.1044"></a>
-<span class="sourceLineNo">1045</span>        LOG.info("Writing .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1045"></a>
-<span class="sourceLineNo">1046</span>      }<a name="line.1046"></a>
-<span class="sourceLineNo">1047</span>      FSDataOutputStream out = fs.create(lastFlushedSeqIdPath);<a name="line.1047"></a>
-<span class="sourceLineNo">1048</span>      FlushedSequenceId.Builder flushedSequenceIdBuilder = FlushedSequenceId.newBuilder();<a name="line.1048"></a>
-<span class="sourceLineNo">1049</span>      try {<a name="line.1049"></a>
-<span class="sourceLineNo">1050</span>        for (Entry&lt;byte[], Long&gt; entry : flushedSequenceIdByRegion.entrySet()) {<a name="line.1050"></a>
-<span class="sourceLineNo">1051</span>          FlushedRegionSequenceId.Builder flushedRegionSequenceIdBuilder =<a name="line.1051"></a>
-<span class="sourceLineNo">1052</span>            FlushedRegionSequenceId.newBuilder();<a name="line.1052"></a>
-<span class="sourceLineNo">1053</span>          flushedRegionSequenceIdBuilder.setRegionEncodedName(ByteString.copyFrom(entry.getKey()));<a name="line.1053"></a>
-<span class="sourceLineNo">1054</span>          flushedRegionSequenceIdBuilder.setSeqId(entry.getValue());<a name="line.1054"></a>
-<span class="sourceLineNo">1055</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeSeqIds =<a name="line.1055"></a>
-<span class="sourceLineNo">1056</span>            storeFlushedSequenceIdsByRegion.get(entry.getKey());<a name="line.1056"></a>
-<span class="sourceLineNo">1057</span>          if (storeSeqIds != null) {<a name="line.1057"></a>
-<span class="sourceLineNo">1058</span>            for (Entry&lt;byte[], Long&gt; store : storeSeqIds.entrySet()) {<a name="line.1058"></a>
-<span class="sourceLineNo">1059</span>              FlushedStoreSequenceId.Builder flushedStoreSequenceIdBuilder =<a name="line.1059"></a>
-<span class="sourceLineNo">1060</span>                FlushedStoreSequenceId.newBuilder();<a name="line.1060"></a>
-<span class="sourceLineNo">1061</span>              flushedStoreSequenceIdBuilder.setFamily(ByteString.copyFrom(store.getKey()));<a name="line.1061"></a>
-<span class="sourceLineNo">1062</span>              flushedStoreSequenceIdBuilder.setSeqId(store.getValue());<a name="line.1062"></a>
-<span class="sourceLineNo">1063</span>              flushedRegionSequenceIdBuilder.addStores(flushedStoreSequenceIdBuilder);<a name="line.1063"></a>
-<span class="sourceLineNo">1064</span>            }<a name="line.1064"></a>
-<span class="sourceLineNo">1065</span>          }<a name="line.1065"></a>
-<span class="sourceLineNo">1066</span>          flushedSequenceIdBuilder.addRegionSequenceId(flushedRegionSequenceIdBuilder);<a name="line.1066"></a>
-<span class="sourceLineNo">1067</span>        }<a name="line.1067"></a>
-<span class="sourceLineNo">1068</span>        flushedSequenceIdBuilder.build().writeDelimitedTo(out);<a name="line.1068"></a>
-<span class="sourceLineNo">1069</span>      } finally {<a name="line.1069"></a>
-<span class="sourceLineNo">1070</span>        if (out != null) {<a name="line.1070"></a>
-<span class="sourceLineNo">1071</span>          out.close();<a name="line.1071"></a>
+<span class="sourceLineNo">1025</span>  public int getInfoPort(ServerName serverName) {<a name="line.1025"></a>
+<span class="sourceLineNo">1026</span>    ServerMetrics serverMetrics = onlineServers.get(serverName);<a name="line.1026"></a>
+<span class="sourceLineNo">1027</span>    return serverMetrics != null ? serverMetrics.getInfoServerPort() : 0;<a name="line.1027"></a>
+<span class="sourceLineNo">1028</span>  }<a name="line.1028"></a>
+<span class="sourceLineNo">1029</span><a name="line.1029"></a>
+<span class="sourceLineNo">1030</span>  /**<a name="line.1030"></a>
+<span class="sourceLineNo">1031</span>   * Persist last flushed sequence id of each region to HDFS<a name="line.1031"></a>
+<span class="sourceLineNo">1032</span>   * @throws IOException if persit to HDFS fails<a name="line.1032"></a>
+<span class="sourceLineNo">1033</span>   */<a name="line.1033"></a>
+<span class="sourceLineNo">1034</span>  private void persistRegionLastFlushedSequenceIds() throws IOException {<a name="line.1034"></a>
+<span class="sourceLineNo">1035</span>    if (isFlushSeqIdPersistInProgress) {<a name="line.1035"></a>
+<span class="sourceLineNo">1036</span>      return;<a name="line.1036"></a>
+<span class="sourceLineNo">1037</span>    }<a name="line.1037"></a>
+<span class="sourceLineNo">1038</span>    isFlushSeqIdPersistInProgress = true;<a name="line.1038"></a>
+<span class="sourceLineNo">1039</span>    try {<a name="line.1039"></a>
+<span class="sourceLineNo">1040</span>      Configuration conf = master.getConfiguration();<a name="line.1040"></a>
+<span class="sourceLineNo">1041</span>      Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1041"></a>
+<span class="sourceLineNo">1042</span>      Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1042"></a>
+<span class="sourceLineNo">1043</span>      FileSystem fs = FileSystem.get(conf);<a name="line.1043"></a>
+<span class="sourceLineNo">1044</span>      if (fs.exists(lastFlushedSeqIdPath)) {<a name="line.1044"></a>
+<span class="sourceLineNo">1045</span>        LOG.info("Rewriting .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1045"></a>
+<span class="sourceLineNo">1046</span>        if (!fs.delete(lastFlushedSeqIdPath, false)) {<a name="line.1046"></a>
+<span class="sourceLineNo">1047</span>          throw new IOException("Unable to remove existing " + lastFlushedSeqIdPath);<a name="line.1047"></a>
+<span class="sourceLineNo">1048</span>        }<a name="line.1048"></a>
+<span class="sourceLineNo">1049</span>      } else {<a name="line.1049"></a>
+<span class="sourceLineNo">1050</span>        LOG.info("Writing .lastflushedseqids file at: " + lastFlushedSeqIdPath);<a name="line.1050"></a>
+<span class="sourceLineNo">1051</span>      }<a name="line.1051"></a>
+<span class="sourceLineNo">1052</span>      FSDataOutputStream out = fs.create(lastFlushedSeqIdPath);<a name="line.1052"></a>
+<span class="sourceLineNo">1053</span>      FlushedSequenceId.Builder flushedSequenceIdBuilder = FlushedSequenceId.newBuilder();<a name="line.1053"></a>
+<span class="sourceLineNo">1054</span>      try {<a name="line.1054"></a>
+<span class="sourceLineNo">1055</span>        for (Entry&lt;byte[], Long&gt; entry : flushedSequenceIdByRegion.entrySet()) {<a name="line.1055"></a>
+<span class="sourceLineNo">1056</span>          FlushedRegionSequenceId.Builder flushedRegionSequenceIdBuilder =<a name="line.1056"></a>
+<span class="sourceLineNo">1057</span>            FlushedRegionSequenceId.newBuilder();<a name="line.1057"></a>
+<span class="sourceLineNo">1058</span>          flushedRegionSequenceIdBuilder.setRegionEncodedName(ByteString.copyFrom(entry.getKey()));<a name="line.1058"></a>
+<span class="sourceLineNo">1059</span>          flushedRegionSequenceIdBuilder.setSeqId(entry.getValue());<a name="line.1059"></a>
+<span class="sourceLineNo">1060</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeSeqIds =<a name="line.1060"></a>
+<span class="sourceLineNo">1061</span>            storeFlushedSequenceIdsByRegion.get(entry.getKey());<a name="line.1061"></a>
+<span class="sourceLineNo">1062</span>          if (storeSeqIds != null) {<a name="line.1062"></a>
+<span class="sourceLineNo">1063</span>            for (Entry&lt;byte[], Long&gt; store : storeSeqIds.entrySet()) {<a name="line.1063"></a>
+<span class="sourceLineNo">1064</span>              FlushedStoreSequenceId.Builder flushedStoreSequenceIdBuilder =<a name="line.1064"></a>
+<span class="sourceLineNo">1065</span>                FlushedStoreSequenceId.newBuilder();<a name="line.1065"></a>
+<span class="sourceLineNo">1066</span>              flushedStoreSequenceIdBuilder.setFamily(ByteString.copyFrom(store.getKey()));<a name="line.1066"></a>
+<span class="sourceLineNo">1067</span>              flushedStoreSequenceIdBuilder.setSeqId(store.getValue());<a name="line.1067"></a>
+<span class="sourceLineNo">1068</span>              flushedRegionSequenceIdBuilder.addStores(flushedStoreSequenceIdBuilder);<a name="line.1068"></a>
+<span class="sourceLineNo">1069</span>            }<a name="line.1069"></a>
+<span class="sourceLineNo">1070</span>          }<a name="line.1070"></a>
+<span class="sourceLineNo">1071</span>          flushedSequenceIdBuilder.addRegionSequenceId(flushedRegionSequenceIdBuilder);<a name="line.1071"></a>
 <span class="sourceLineNo">1072</span>        }<a name="line.1072"></a>
-<span class="sourceLineNo">1073</span>      }<a name="line.1073"></a>
-<span class="sourceLineNo">1074</span>    } finally {<a name="line.1074"></a>
-<span class="sourceLineNo">1075</span>      isFlushSeqIdPersistInProgress = false;<a name="line.1075"></a>
-<span class="sourceLineNo">1076</span>    }<a name="line.1076"></a>
-<span class="sourceLineNo">1077</span>  }<a name="line.1077"></a>
-<span class="sourceLineNo">1078</span><a name="line.1078"></a>
-<span class="sourceLineNo">1079</span>  /**<a name="line.1079"></a>
-<span class="sourceLineNo">1080</span>   * Load last flushed sequence id of each region from HDFS, if persisted<a name="line.1080"></a>
-<span class="sourceLineNo">1081</span>   */<a name="line.1081"></a>
-<span class="sourceLineNo">1082</span>  public void loadLastFlushedSequenceIds() throws IOException {<a name="line.1082"></a>
-<span class="sourceLineNo">1083</span>    if (!persistFlushedSequenceId) {<a name="line.1083"></a>
-<span class="sourceLineNo">1084</span>      return;<a name="line.1084"></a>
-<span class="sourceLineNo">1085</span>    }<a name="line.1085"></a>
-<span class="sourceLineNo">1086</span>    Configuration conf = master.getConfiguration();<a name="line.1086"></a>
-<span class="sourceLineNo">1087</span>    Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1087"></a>
-<span class="sourceLineNo">1088</span>    Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1088"></a>
-<span class="sourceLineNo">1089</span>    FileSystem fs = FileSystem.get(conf);<a name="line.1089"></a>
-<span class="sourceLineNo">1090</span>    if (!fs.exists(lastFlushedSeqIdPath)) {<a name="line.1090"></a>
-<span class="sourceLineNo">1091</span>      LOG.info("No .lastflushedseqids found at " + lastFlushedSeqIdPath<a name="line.1091"></a>
-<span class="sourceLineNo">1092</span>        + " will record last flushed sequence id"<a name="line.1092"></a>
-<span class="sourceLineNo">1093</span>        + " for regions by regionserver report all over again");<a name="line.1093"></a>
-<span class="sourceLineNo">1094</span>      return;<a name="line.1094"></a>
-<span class="sourceLineNo">1095</span>    } else {<a name="line.1095"></a>
-<span class="sourceLineNo">1096</span>      LOG.info("begin to load .lastflushedseqids at " + lastFlushedSeqIdPath);<a name="line.1096"></a>
-<span class="sourceLineNo">1097</span>    }<a name="line.1097"></a>
-<span class="sourceLineNo">1098</span>    FSDataInputStream in = fs.open(lastFlushedSeqIdPath);<a name="line.1098"></a>
-<span class="sourceLineNo">1099</span>    try {<a name="line.1099"></a>
-<span class="sourceLineNo">1100</span>      FlushedSequenceId flushedSequenceId = FlushedSequenceId.parseDelimitedFrom(in);<a name="line.1100"></a>
-<span class="sourceLineNo">1101</span>      if (flushedSequenceId == null) {<a name="line.1101"></a>
-<span class="sourceLineNo">1102</span>        LOG.info(".lastflushedseqids found at {} is empty", lastFlushedSeqIdPath);<a name="line.1102"></a>
-<span class="sourceLineNo">1103</span>        return;<a name="line.1103"></a>
-<span class="sourceLineNo">1104</span>      }<a name="line.1104"></a>
-<span class="sourceLineNo">1105</span>      for (FlushedRegionSequenceId flushedRegionSequenceId : flushedSequenceId<a name="line.1105"></a>
-<span class="sourceLineNo">1106</span>        .getRegionSequenceIdList()) {<a name="line.1106"></a>
-<span class="sourceLineNo">1107</span>        byte[] encodedRegionName = flushedRegionSequenceId.getRegionEncodedName().toByteArray();<a name="line.1107"></a>
-<span class="sourceLineNo">1108</span>        flushedSequenceIdByRegion.putIfAbsent(encodedRegionName,<a name="line.1108"></a>
-<span class="sourceLineNo">1109</span>          flushedRegionSequenceId.getSeqId());<a name="line.1109"></a>
-<span class="sourceLineNo">1110</span>        if (<a name="line.1110"></a>
-<span class="sourceLineNo">1111</span>          flushedRegionSequenceId.getStoresList() != null<a name="line.1111"></a>
-<span class="sourceLineNo">1112</span>            &amp;&amp; flushedRegionSequenceId.getStoresList().size() != 0<a name="line.1112"></a>
-<span class="sourceLineNo">1113</span>        ) {<a name="line.1113"></a>
-<span class="sourceLineNo">1114</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.1114"></a>
-<span class="sourceLineNo">1115</span>            computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.1115"></a>
-<span class="sourceLineNo">1116</span>              () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.1116"></a>
-<span class="sourceLineNo">1117</span>          for (FlushedStoreSequenceId flushedStoreSequenceId : flushedRegionSequenceId<a name="line.1117"></a>
-<span class="sourceLineNo">1118</span>            .getStoresList()) {<a name="line.1118"></a>
-<span class="sourceLineNo">1119</span>            storeFlushedSequenceId.put(flushedStoreSequenceId.getFamily().toByteArray(),<a name="line.1119"></a>
-<span class="sourceLineNo">1120</span>              flushedStoreSequenceId.getSeqId());<a name="line.1120"></a>
-<span class="sourceLineNo">1121</span>          }<a name="line.1121"></a>
-<span class="sourceLineNo">1122</span>        }<a name="line.1122"></a>
-<span class="sourceLineNo">1123</span>      }<a name="line.1123"></a>
-<span class="sourceLineNo">1124</span>    } finally {<a name="line.1124"></a>
-<span class="sourceLineNo">1125</span>      in.close();<a name="line.1125"></a>
-<span class="sourceLineNo">1126</span>    }<a name="line.1126"></a>
-<span class="sourceLineNo">1127</span>  }<a name="line.1127"></a>
-<span class="sourceLineNo">1128</span><a name="line.1128"></a>
-<span class="sourceLineNo">1129</span>  /**<a name="line.1129"></a>
-<span class="sourceLineNo">1130</span>   * Regions may have been removed between latest persist of FlushedSequenceIds and master abort. So<a name="line.1130"></a>
-<span class="sourceLineNo">1131</span>   * after loading FlushedSequenceIds from file, and after meta loaded, we need to remove the<a name="line.1131"></a>
-<span class="sourceLineNo">1132</span>   * deleted region according to RegionStates.<a name="line.1132"></a>
-<span class="sourceLineNo">1133</span>   */<a name="line.1133"></a>
-<span class="sourceLineNo">1134</span>  public void removeDeletedRegionFromLoadedFlushedSequenceIds() {<a name="line.1134"></a>
-<span class="sourceLineNo">1135</span>    RegionStates regionStates = master.getAssignmentManager().getRegionStates();<a name="line.1135"></a>
-<span class="sourceLineNo">1136</span>    Iterator&lt;byte[]&gt; it = flushedSequenceIdByRegion.keySet().iterator();<a name="line.1136"></a>
-<span class="sourceLineNo">1137</span>    while (it.hasNext()) {<a name="line.1137"></a>
-<span class="sourceLineNo">1138</span>      byte[] regionEncodedName = it.next();<a name="line.1138"></a>
-<span class="sourceLineNo">1139</span>      if (regionStates.getRegionState(Bytes.toStringBinary(regionEncodedName)) == null) {<a name="line.1139"></a>
-<span class="sourceLineNo">1140</span>        it.remove();<a name="line.1140"></a>
-<span class="sourceLineNo">1141</span>        storeFlushedSequenceIdsByRegion.remove(regionEncodedName);<a name="line.1141"></a>
-<span class="sourceLineNo">1142</span>      }<a name="line.1142"></a>
-<span class="sourceLineNo">1143</span>    }<a name="line.1143"></a>
-<span class="sourceLineNo">1144</span>  }<a name="line.1144"></a>
-<span class="sourceLineNo">1145</span><a name="line.1145"></a>
-<span class="sourceLineNo">1146</span>  private class FlushedSequenceIdFlusher extends ScheduledChore {<a name="line.1146"></a>
-<span class="sourceLineNo">1147</span><a name="line.1147"></a>
-<span class="sourceLineNo">1148</span>    public FlushedSequenceIdFlusher(String name, int p) {<a name="line.1148"></a>
-<span class="sourceLineNo">1149</span>      super(name, master, p, 60 * 1000); // delay one minute before first execute<a name="line.1149"></a>
-<span class="sourceLineNo">1150</span>    }<a name="line.1150"></a>
-<span class="sourceLineNo">1151</span><a name="line.1151"></a>
-<span class="sourceLineNo">1152</span>    @Override<a name="line.1152"></a>
-<span class="sourceLineNo">1153</span>    protected void chore() {<a name="line.1153"></a>
-<span class="sourceLineNo">1154</span>      try {<a name="line.1154"></a>
-<span class="sourceLineNo">1155</span>        persistRegionLastFlushedSequenceIds();<a name="line.1155"></a>
-<span class="sourceLineNo">1156</span>      } catch (IOException e) {<a name="line.1156"></a>
-<span class="sourceLineNo">1157</span>        LOG.debug("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.1157"></a>
-<span class="sourceLineNo">1158</span>      }<a name="line.1158"></a>
-<span class="sourceLineNo">1159</span>    }<a name="line.1159"></a>
-<span class="sourceLineNo">1160</span>  }<a name="line.1160"></a>
-<span class="sourceLineNo">1161</span>}<a name="line.1161"></a>
+<span class="sourceLineNo">1073</span>        flushedSequenceIdBuilder.build().writeDelimitedTo(out);<a name="line.1073"></a>
+<span class="sourceLineNo">1074</span>      } finally {<a name="line.1074"></a>
+<span class="sourceLineNo">1075</span>        if (out != null) {<a name="line.1075"></a>
+<span class="sourceLineNo">1076</span>          out.close();<a name="line.1076"></a>
+<span class="sourceLineNo">1077</span>        }<a name="line.1077"></a>
+<span class="sourceLineNo">1078</span>      }<a name="line.1078"></a>
+<span class="sourceLineNo">1079</span>    } finally {<a name="line.1079"></a>
+<span class="sourceLineNo">1080</span>      isFlushSeqIdPersistInProgress = false;<a name="line.1080"></a>
+<span class="sourceLineNo">1081</span>    }<a name="line.1081"></a>
+<span class="sourceLineNo">1082</span>  }<a name="line.1082"></a>
+<span class="sourceLineNo">1083</span><a name="line.1083"></a>
+<span class="sourceLineNo">1084</span>  /**<a name="line.1084"></a>
+<span class="sourceLineNo">1085</span>   * Load last flushed sequence id of each region from HDFS, if persisted<a name="line.1085"></a>
+<span class="sourceLineNo">1086</span>   */<a name="line.1086"></a>
+<span class="sourceLineNo">1087</span>  public void loadLastFlushedSequenceIds() throws IOException {<a name="line.1087"></a>
+<span class="sourceLineNo">1088</span>    if (!persistFlushedSequenceId) {<a name="line.1088"></a>
+<span class="sourceLineNo">1089</span>      return;<a name="line.1089"></a>
+<span class="sourceLineNo">1090</span>    }<a name="line.1090"></a>
+<span class="sourceLineNo">1091</span>    Configuration conf = master.getConfiguration();<a name="line.1091"></a>
+<span class="sourceLineNo">1092</span>    Path rootDir = CommonFSUtils.getRootDir(conf);<a name="line.1092"></a>
+<span class="sourceLineNo">1093</span>    Path lastFlushedSeqIdPath = new Path(rootDir, LAST_FLUSHED_SEQ_ID_FILE);<a name="line.1093"></a>
+<span class="sourceLineNo">1094</span>    FileSystem fs = FileSystem.get(conf);<a name="line.1094"></a>
+<span class="sourceLineNo">1095</span>    if (!fs.exists(lastFlushedSeqIdPath)) {<a name="line.1095"></a>
+<span class="sourceLineNo">1096</span>      LOG.info("No .lastflushedseqids found at " + lastFlushedSeqIdPath<a name="line.1096"></a>
+<span class="sourceLineNo">1097</span>        + " will record last flushed sequence id"<a name="line.1097"></a>
+<span class="sourceLineNo">1098</span>        + " for regions by regionserver report all over again");<a name="line.1098"></a>
+<span class="sourceLineNo">1099</span>      return;<a name="line.1099"></a>
+<span class="sourceLineNo">1100</span>    } else {<a name="line.1100"></a>
+<span class="sourceLineNo">1101</span>      LOG.info("begin to load .lastflushedseqids at " + lastFlushedSeqIdPath);<a name="line.1101"></a>
+<span class="sourceLineNo">1102</span>    }<a name="line.1102"></a>
+<span class="sourceLineNo">1103</span>    FSDataInputStream in = fs.open(lastFlushedSeqIdPath);<a name="line.1103"></a>
+<span class="sourceLineNo">1104</span>    try {<a name="line.1104"></a>
+<span class="sourceLineNo">1105</span>      FlushedSequenceId flushedSequenceId = FlushedSequenceId.parseDelimitedFrom(in);<a name="line.1105"></a>
+<span class="sourceLineNo">1106</span>      if (flushedSequenceId == null) {<a name="line.1106"></a>
+<span class="sourceLineNo">1107</span>        LOG.info(".lastflushedseqids found at {} is empty", lastFlushedSeqIdPath);<a name="line.1107"></a>
+<span class="sourceLineNo">1108</span>        return;<a name="line.1108"></a>
+<span class="sourceLineNo">1109</span>      }<a name="line.1109"></a>
+<span class="sourceLineNo">1110</span>      for (FlushedRegionSequenceId flushedRegionSequenceId : flushedSequenceId<a name="line.1110"></a>
+<span class="sourceLineNo">1111</span>        .getRegionSequenceIdList()) {<a name="line.1111"></a>
+<span class="sourceLineNo">1112</span>        byte[] encodedRegionName = flushedRegionSequenceId.getRegionEncodedName().toByteArray();<a name="line.1112"></a>
+<span class="sourceLineNo">1113</span>        flushedSequenceIdByRegion.putIfAbsent(encodedRegionName,<a name="line.1113"></a>
+<span class="sourceLineNo">1114</span>          flushedRegionSequenceId.getSeqId());<a name="line.1114"></a>
+<span class="sourceLineNo">1115</span>        if (<a name="line.1115"></a>
+<span class="sourceLineNo">1116</span>          flushedRegionSequenceId.getStoresList() != null<a name="line.1116"></a>
+<span class="sourceLineNo">1117</span>            &amp;&amp; flushedRegionSequenceId.getStoresList().size() != 0<a name="line.1117"></a>
+<span class="sourceLineNo">1118</span>        ) {<a name="line.1118"></a>
+<span class="sourceLineNo">1119</span>          ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.1119"></a>
+<span class="sourceLineNo">1120</span>            computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.1120"></a>
+<span class="sourceLineNo">1121</span>              () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.1121"></a>
+<span class="sourceLineNo">1122</span>          for (FlushedStoreSequenceId flushedStoreSequenceId : flushedRegionSequenceId<a name="line.1122"></a>
+<span class="sourceLineNo">1123</span>            .getStoresList()) {<a name="line.1123"></a>
+<span class="sourceLineNo">1124</span>            storeFlushedSequenceId.put(flushedStoreSequenceId.getFamily().toByteArray(),<a name="line.1124"></a>
+<span class="sourceLineNo">1125</span>              flushedStoreSequenceId.getSeqId());<a name="line.1125"></a>
+<span class="sourceLineNo">1126</span>          }<a name="line.1126"></a>
+<span class="sourceLineNo">1127</span>        }<a name="line.1127"></a>
+<span class="sourceLineNo">1128</span>      }<a name="line.1128"></a>
+<span class="sourceLineNo">1129</span>    } finally {<a name="line.1129"></a>
+<span class="sourceLineNo">1130</span>      in.close();<a name="line.1130"></a>
+<span class="sourceLineNo">1131</span>    }<a name="line.1131"></a>
+<span class="sourceLineNo">1132</span>  }<a name="line.1132"></a>
+<span class="sourceLineNo">1133</span><a name="line.1133"></a>
+<span class="sourceLineNo">1134</span>  /**<a name="line.1134"></a>
+<span class="sourceLineNo">1135</span>   * Regions may have been removed between latest persist of FlushedSequenceIds and master abort. So<a name="line.1135"></a>
+<span class="sourceLineNo">1136</span>   * after loading FlushedSequenceIds from file, and after meta loaded, we need to remove the<a name="line.1136"></a>
+<span class="sourceLineNo">1137</span>   * deleted region according to RegionStates.<a name="line.1137"></a>
+<span class="sourceLineNo">1138</span>   */<a name="line.1138"></a>
+<span class="sourceLineNo">1139</span>  public void removeDeletedRegionFromLoadedFlushedSequenceIds() {<a name="line.1139"></a>
+<span class="sourceLineNo">1140</span>    RegionStates regionStates = master.getAssignmentManager().getRegionStates();<a name="line.1140"></a>
+<span class="sourceLineNo">1141</span>    Iterator&lt;byte[]&gt; it = flushedSequenceIdByRegion.keySet().iterator();<a name="line.1141"></a>
+<span class="sourceLineNo">1142</span>    while (it.hasNext()) {<a name="line.1142"></a>
+<span class="sourceLineNo">1143</span>      byte[] regionEncodedName = it.next();<a name="line.1143"></a>
+<span class="sourceLineNo">1144</span>      if (regionStates.getRegionState(Bytes.toStringBinary(regionEncodedName)) == null) {<a name="line.1144"></a>
+<span class="sourceLineNo">1145</span>        it.remove();<a name="line.1145"></a>
+<span class="sourceLineNo">1146</span>        storeFlushedSequenceIdsByRegion.remove(regionEncodedName);<a name="line.1146"></a>
+<span class="sourceLineNo">1147</span>      }<a name="line.1147"></a>
+<span class="sourceLineNo">1148</span>    }<a name="line.1148"></a>
+<span class="sourceLineNo">1149</span>  }<a name="line.1149"></a>
+<span class="sourceLineNo">1150</span><a name="line.1150"></a>
+<span class="sourceLineNo">1151</span>  private class FlushedSequenceIdFlusher extends ScheduledChore {<a name="line.1151"></a>
+<span class="sourceLineNo">1152</span><a name="line.1152"></a>
+<span class="sourceLineNo">1153</span>    public FlushedSequenceIdFlusher(String name, int p) {<a name="line.1153"></a>
+<span class="sourceLineNo">1154</span>      super(name, master, p, 60 * 1000); // delay one minute before first execute<a name="line.1154"></a>
+<span class="sourceLineNo">1155</span>    }<a name="line.1155"></a>
+<span class="sourceLineNo">1156</span><a name="line.1156"></a>
+<span class="sourceLineNo">1157</span>    @Override<a name="line.1157"></a>
+<span class="sourceLineNo">1158</span>    protected void chore() {<a name="line.1158"></a>
+<span class="sourceLineNo">1159</span>      try {<a name="line.1159"></a>
+<span class="sourceLineNo">1160</span>        persistRegionLastFlushedSequenceIds();<a name="line.1160"></a>
+<span class="sourceLineNo">1161</span>      } catch (IOException e) {<a name="line.1161"></a>
+<span class="sourceLineNo">1162</span>        LOG.debug("Failed to persist last flushed sequence id of regions" + " to file system", e);<a name="line.1162"></a>
+<span class="sourceLineNo">1163</span>      }<a name="line.1163"></a>
+<span class="sourceLineNo">1164</span>    }<a name="line.1164"></a>
+<span class="sourceLineNo">1165</span>  }<a name="line.1165"></a>
+<span class="sourceLineNo">1166</span>}<a name="line.1166"></a>
 
 
 
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.html b/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.html
index 140134dec90..89e1e0e9915 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.html
+++ b/devapidocs/src-html/org/apache/hadoop/hbase/master/ServerManager.html
@@ -227,946 +227,951 @@
 <span class="sourceLineNo">219</span>    // in, it should have been removed from serverAddressToServerInfo and queued<a name="line.219"></a>
 <span class="sourceLineNo">220</span>    // for processing by ProcessServerShutdown.<a name="line.220"></a>
 <span class="sourceLineNo">221</span><a name="line.221"></a>
-<span class="sourceLineNo">222</span>    final String hostname =<a name="line.222"></a>
-<span class="sourceLineNo">223</span>      request.hasUseThisHostnameInstead() ? request.getUseThisHostnameInstead() : ia.getHostName();<a name="line.223"></a>
-<span class="sourceLineNo">224</span>    ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());<a name="line.224"></a>
-<span class="sourceLineNo">225</span>    checkClockSkew(sn, request.getServerCurrentTime());<a name="line.225"></a>
-<span class="sourceLineNo">226</span>    checkIsDead(sn, "STARTUP");<a name="line.226"></a>
-<span class="sourceLineNo">227</span>    if (!checkAndRecordNewServer(sn, ServerMetricsBuilder.of(sn, versionNumber, version))) {<a name="line.227"></a>
-<span class="sourceLineNo">228</span>      LOG.warn(<a name="line.228"></a>
-<span class="sourceLineNo">229</span>        "THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);<a name="line.229"></a>
-<span class="sourceLineNo">230</span>    }<a name="line.230"></a>
-<span class="sourceLineNo">231</span>    storage.started(sn);<a name="line.231"></a>
-<span class="sourceLineNo">232</span>    return sn;<a name="line.232"></a>
-<span class="sourceLineNo">233</span>  }<a name="line.233"></a>
-<span class="sourceLineNo">234</span><a name="line.234"></a>
-<span class="sourceLineNo">235</span>  /**<a name="line.235"></a>
-<span class="sourceLineNo">236</span>   * Updates last flushed sequence Ids for the regions on server sn<a name="line.236"></a>
-<span class="sourceLineNo">237</span>   */<a name="line.237"></a>
-<span class="sourceLineNo">238</span>  private void updateLastFlushedSequenceIds(ServerName sn, ServerMetrics hsl) {<a name="line.238"></a>
-<span class="sourceLineNo">239</span>    for (Entry&lt;byte[], RegionMetrics&gt; entry : hsl.getRegionMetrics().entrySet()) {<a name="line.239"></a>
-<span class="sourceLineNo">240</span>      byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey()));<a name="line.240"></a>
-<span class="sourceLineNo">241</span>      Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.241"></a>
-<span class="sourceLineNo">242</span>      long l = entry.getValue().getCompletedSequenceId();<a name="line.242"></a>
-<span class="sourceLineNo">243</span>      // Don't let smaller sequence ids override greater sequence ids.<a name="line.243"></a>
-<span class="sourceLineNo">244</span>      if (LOG.isTraceEnabled()) {<a name="line.244"></a>
-<span class="sourceLineNo">245</span>        LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue<a name="line.245"></a>
-<span class="sourceLineNo">246</span>          + ", completeSequenceId=" + l);<a name="line.246"></a>
-<span class="sourceLineNo">247</span>      }<a name="line.247"></a>
-<span class="sourceLineNo">248</span>      if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue)) {<a name="line.248"></a>
-<span class="sourceLineNo">249</span>        flushedSequenceIdByRegion.put(encodedRegionName, l);<a name="line.249"></a>
-<span class="sourceLineNo">250</span>      } else if (l != HConstants.NO_SEQNUM &amp;&amp; l &lt; existingValue) {<a name="line.250"></a>
-<span class="sourceLineNo">251</span>        LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l<a name="line.251"></a>
-<span class="sourceLineNo">252</span>          + ") that is less than the previous last flushed sequence id (" + existingValue<a name="line.252"></a>
-<span class="sourceLineNo">253</span>          + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring.");<a name="line.253"></a>
-<span class="sourceLineNo">254</span>      }<a name="line.254"></a>
-<span class="sourceLineNo">255</span>      ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.255"></a>
-<span class="sourceLineNo">256</span>        computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.256"></a>
-<span class="sourceLineNo">257</span>          () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.257"></a>
-<span class="sourceLineNo">258</span>      for (Entry&lt;byte[], Long&gt; storeSeqId : entry.getValue().getStoreSequenceId().entrySet()) {<a name="line.258"></a>
-<span class="sourceLineNo">259</span>        byte[] family = storeSeqId.getKey();<a name="line.259"></a>
-<span class="sourceLineNo">260</span>        existingValue = storeFlushedSequenceId.get(family);<a name="line.260"></a>
-<span class="sourceLineNo">261</span>        l = storeSeqId.getValue();<a name="line.261"></a>
-<span class="sourceLineNo">262</span>        if (LOG.isTraceEnabled()) {<a name="line.262"></a>
-<span class="sourceLineNo">263</span>          LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family)<a name="line.263"></a>
-<span class="sourceLineNo">264</span>            + ", existingValue=" + existingValue + ", completeSequenceId=" + l);<a name="line.264"></a>
-<span class="sourceLineNo">265</span>        }<a name="line.265"></a>
-<span class="sourceLineNo">266</span>        // Don't let smaller sequence ids override greater sequence ids.<a name="line.266"></a>
-<span class="sourceLineNo">267</span>        if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue.longValue())) {<a name="line.267"></a>
-<span class="sourceLineNo">268</span>          storeFlushedSequenceId.put(family, l);<a name="line.268"></a>
-<span class="sourceLineNo">269</span>        }<a name="line.269"></a>
-<span class="sourceLineNo">270</span>      }<a name="line.270"></a>
-<span class="sourceLineNo">271</span>    }<a name="line.271"></a>
-<span class="sourceLineNo">272</span>  }<a name="line.272"></a>
-<span class="sourceLineNo">273</span><a name="line.273"></a>
-<span class="sourceLineNo">274</span>  public void regionServerReport(ServerName sn, ServerMetrics sl) throws YouAreDeadException {<a name="line.274"></a>
-<span class="sourceLineNo">275</span>    checkIsDead(sn, "REPORT");<a name="line.275"></a>
-<span class="sourceLineNo">276</span>    if (null == this.onlineServers.replace(sn, sl)) {<a name="line.276"></a>
-<span class="sourceLineNo">277</span>      // Already have this host+port combo and its just different start code?<a name="line.277"></a>
-<span class="sourceLineNo">278</span>      // Just let the server in. Presume master joining a running cluster.<a name="line.278"></a>
-<span class="sourceLineNo">279</span>      // recordNewServer is what happens at the end of reportServerStartup.<a name="line.279"></a>
-<span class="sourceLineNo">280</span>      // The only thing we are skipping is passing back to the regionserver<a name="line.280"></a>
-<span class="sourceLineNo">281</span>      // the ServerName to use. Here we presume a master has already done<a name="line.281"></a>
-<span class="sourceLineNo">282</span>      // that so we'll press on with whatever it gave us for ServerName.<a name="line.282"></a>
-<span class="sourceLineNo">283</span>      if (!checkAndRecordNewServer(sn, sl)) {<a name="line.283"></a>
-<span class="sourceLineNo">284</span>        LOG.info("RegionServerReport ignored, could not record the server: " + sn);<a name="line.284"></a>
-<span class="sourceLineNo">285</span>        return; // Not recorded, so no need to move on<a name="line.285"></a>
-<span class="sourceLineNo">286</span>      }<a name="line.286"></a>
-<span class="sourceLineNo">287</span>    }<a name="line.287"></a>
-<span class="sourceLineNo">288</span>    updateLastFlushedSequenceIds(sn, sl);<a name="line.288"></a>
-<span class="sourceLineNo">289</span>  }<a name="line.289"></a>
-<span class="sourceLineNo">290</span><a name="line.290"></a>
-<span class="sourceLineNo">291</span>  /**<a name="line.291"></a>
-<span class="sourceLineNo">292</span>   * Check is a server of same host and port already exists, if not, or the existed one got a<a name="line.292"></a>
-<span class="sourceLineNo">293</span>   * smaller start code, record it.<a name="line.293"></a>
-<span class="sourceLineNo">294</span>   * @param serverName the server to check and record<a name="line.294"></a>
-<span class="sourceLineNo">295</span>   * @param sl         the server load on the server<a name="line.295"></a>
-<span class="sourceLineNo">296</span>   * @return true if the server is recorded, otherwise, false<a name="line.296"></a>
-<span class="sourceLineNo">297</span>   */<a name="line.297"></a>
-<span class="sourceLineNo">298</span>  boolean checkAndRecordNewServer(final ServerName serverName, final ServerMetrics sl) {<a name="line.298"></a>
-<span class="sourceLineNo">299</span>    ServerName existingServer = null;<a name="line.299"></a>
-<span class="sourceLineNo">300</span>    synchronized (this.onlineServers) {<a name="line.300"></a>
-<span class="sourceLineNo">301</span>      existingServer = findServerWithSameHostnamePortWithLock(serverName);<a name="line.301"></a>
-<span class="sourceLineNo">302</span>      if (existingServer != null &amp;&amp; (existingServer.getStartcode() &gt; serverName.getStartcode())) {<a name="line.302"></a>
-<span class="sourceLineNo">303</span>        LOG.info("Server serverName=" + serverName + " rejected; we already have "<a name="line.303"></a>
-<span class="sourceLineNo">304</span>          + existingServer.toString() + " registered with same hostname and port");<a name="line.304"></a>
-<span class="sourceLineNo">305</span>        return false;<a name="line.305"></a>
-<span class="sourceLineNo">306</span>      }<a name="line.306"></a>
-<span class="sourceLineNo">307</span>      recordNewServerWithLock(serverName, sl);<a name="line.307"></a>
-<span class="sourceLineNo">308</span>    }<a name="line.308"></a>
-<span class="sourceLineNo">309</span><a name="line.309"></a>
-<span class="sourceLineNo">310</span>    // Tell our listeners that a server was added<a name="line.310"></a>
-<span class="sourceLineNo">311</span>    if (!this.listeners.isEmpty()) {<a name="line.311"></a>
-<span class="sourceLineNo">312</span>      for (ServerListener listener : this.listeners) {<a name="line.312"></a>
-<span class="sourceLineNo">313</span>        listener.serverAdded(serverName);<a name="line.313"></a>
-<span class="sourceLineNo">314</span>      }<a name="line.314"></a>
-<span class="sourceLineNo">315</span>    }<a name="line.315"></a>
-<span class="sourceLineNo">316</span><a name="line.316"></a>
-<span class="sourceLineNo">317</span>    // Note that we assume that same ts means same server, and don't expire in that case.<a name="line.317"></a>
-<span class="sourceLineNo">318</span>    // TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.<a name="line.318"></a>
-<span class="sourceLineNo">319</span>    if (existingServer != null &amp;&amp; (existingServer.getStartcode() &lt; serverName.getStartcode())) {<a name="line.319"></a>
-<span class="sourceLineNo">320</span>      LOG.info("Triggering server recovery; existingServer " + existingServer<a name="line.320"></a>
-<span class="sourceLineNo">321</span>        + " looks stale, new server:" + serverName);<a name="line.321"></a>
-<span class="sourceLineNo">322</span>      expireServer(existingServer);<a name="line.322"></a>
-<span class="sourceLineNo">323</span>    }<a name="line.323"></a>
-<span class="sourceLineNo">324</span>    return true;<a name="line.324"></a>
-<span class="sourceLineNo">325</span>  }<a name="line.325"></a>
-<span class="sourceLineNo">326</span><a name="line.326"></a>
-<span class="sourceLineNo">327</span>  /**<a name="line.327"></a>
-<span class="sourceLineNo">328</span>   * Find out the region servers crashed between the crash of the previous master instance and the<a name="line.328"></a>
-<span class="sourceLineNo">329</span>   * current master instance and schedule SCP for them.<a name="line.329"></a>
-<span class="sourceLineNo">330</span>   * &lt;p/&gt;<a name="line.330"></a>
-<span class="sourceLineNo">331</span>   * Since the {@code RegionServerTracker} has already helped us to construct the online servers set<a name="line.331"></a>
-<span class="sourceLineNo">332</span>   * by scanning zookeeper, now we can compare the online servers with {@code liveServersFromWALDir}<a name="line.332"></a>
-<span class="sourceLineNo">333</span>   * to find out whether there are servers which are already dead.<a name="line.333"></a>
-<span class="sourceLineNo">334</span>   * &lt;p/&gt;<a name="line.334"></a>
-<span class="sourceLineNo">335</span>   * Must be called inside the initialization method of {@code RegionServerTracker} to avoid<a name="line.335"></a>
-<span class="sourceLineNo">336</span>   * concurrency issue.<a name="line.336"></a>
-<span class="sourceLineNo">337</span>   * @param deadServersFromPE     the region servers which already have a SCP associated.<a name="line.337"></a>
-<span class="sourceLineNo">338</span>   * @param liveServersFromWALDir the live region servers from wal directory.<a name="line.338"></a>
-<span class="sourceLineNo">339</span>   */<a name="line.339"></a>
-<span class="sourceLineNo">340</span>  void findDeadServersAndProcess(Set&lt;ServerName&gt; deadServersFromPE,<a name="line.340"></a>
-<span class="sourceLineNo">341</span>    Set&lt;ServerName&gt; liveServersFromWALDir) {<a name="line.341"></a>
-<span class="sourceLineNo">342</span>    deadServersFromPE.forEach(deadservers::putIfAbsent);<a name="line.342"></a>
-<span class="sourceLineNo">343</span>    liveServersFromWALDir.stream().filter(sn -&gt; !onlineServers.containsKey(sn))<a name="line.343"></a>
-<span class="sourceLineNo">344</span>      .forEach(this::expireServer);<a name="line.344"></a>
-<span class="sourceLineNo">345</span>  }<a name="line.345"></a>
-<span class="sourceLineNo">346</span><a name="line.346"></a>
-<span class="sourceLineNo">347</span>  /**<a name="line.347"></a>
-<span class="sourceLineNo">348</span>   * Checks if the clock skew between the server and the master. If the clock skew exceeds the<a name="line.348"></a>
-<span class="sourceLineNo">349</span>   * configured max, it will throw an exception; if it exceeds the configured warning threshold, it<a name="line.349"></a>
-<span class="sourceLineNo">350</span>   * will log a warning but start normally.<a name="line.350"></a>
-<span class="sourceLineNo">351</span>   * @param serverName Incoming servers's name n * @throws ClockOutOfSyncException if the skew<a name="line.351"></a>
-<span class="sourceLineNo">352</span>   *                   exceeds the configured max value<a name="line.352"></a>
-<span class="sourceLineNo">353</span>   */<a name="line.353"></a>
-<span class="sourceLineNo">354</span>  private void checkClockSkew(final ServerName serverName, final long serverCurrentTime)<a name="line.354"></a>
-<span class="sourceLineNo">355</span>    throws ClockOutOfSyncException {<a name="line.355"></a>
-<span class="sourceLineNo">356</span>    long skew = Math.abs(EnvironmentEdgeManager.currentTime() - serverCurrentTime);<a name="line.356"></a>
-<span class="sourceLineNo">357</span>    if (skew &gt; maxSkew) {<a name="line.357"></a>
-<span class="sourceLineNo">358</span>      String message = "Server " + serverName + " has been "<a name="line.358"></a>
-<span class="sourceLineNo">359</span>        + "rejected; Reported time is too far out of sync with master.  " + "Time difference of "<a name="line.359"></a>
-<span class="sourceLineNo">360</span>        + skew + "ms &gt; max allowed of " + maxSkew + "ms";<a name="line.360"></a>
-<span class="sourceLineNo">361</span>      LOG.warn(message);<a name="line.361"></a>
-<span class="sourceLineNo">362</span>      throw new ClockOutOfSyncException(message);<a name="line.362"></a>
-<span class="sourceLineNo">363</span>    } else if (skew &gt; warningSkew) {<a name="line.363"></a>
-<span class="sourceLineNo">364</span>      String message = "Reported time for server " + serverName + " is out of sync with master "<a name="line.364"></a>
-<span class="sourceLineNo">365</span>        + "by " + skew + "ms. (Warning threshold is " + warningSkew + "ms; " + "error threshold is "<a name="line.365"></a>
-<span class="sourceLineNo">366</span>        + maxSkew + "ms)";<a name="line.366"></a>
-<span class="sourceLineNo">367</span>      LOG.warn(message);<a name="line.367"></a>
-<span class="sourceLineNo">368</span>    }<a name="line.368"></a>
-<span class="sourceLineNo">369</span>  }<a name="line.369"></a>
-<span class="sourceLineNo">370</span><a name="line.370"></a>
-<span class="sourceLineNo">371</span>  /**<a name="line.371"></a>
-<span class="sourceLineNo">372</span>   * Called when RegionServer first reports in for duty and thereafter each time it heartbeats to<a name="line.372"></a>
-<span class="sourceLineNo">373</span>   * make sure it is has not been figured for dead. If this server is on the dead list, reject it<a name="line.373"></a>
-<span class="sourceLineNo">374</span>   * with a YouAreDeadException. If it was dead but came back with a new start code, remove the old<a name="line.374"></a>
-<span class="sourceLineNo">375</span>   * entry from the dead list.<a name="line.375"></a>
-<span class="sourceLineNo">376</span>   * @param what START or REPORT<a name="line.376"></a>
-<span class="sourceLineNo">377</span>   */<a name="line.377"></a>
-<span class="sourceLineNo">378</span>  private void checkIsDead(final ServerName serverName, final String what)<a name="line.378"></a>
-<span class="sourceLineNo">379</span>    throws YouAreDeadException {<a name="line.379"></a>
-<span class="sourceLineNo">380</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.380"></a>
-<span class="sourceLineNo">381</span>      // Exact match: host name, port and start code all match with existing one of the<a name="line.381"></a>
-<span class="sourceLineNo">382</span>      // dead servers. So, this server must be dead. Tell it to kill itself.<a name="line.382"></a>
-<span class="sourceLineNo">383</span>      String message =<a name="line.383"></a>
-<span class="sourceLineNo">384</span>        "Server " + what + " rejected; currently processing " + serverName + " as dead server";<a name="line.384"></a>
-<span class="sourceLineNo">385</span>      LOG.debug(message);<a name="line.385"></a>
-<span class="sourceLineNo">386</span>      throw new YouAreDeadException(message);<a name="line.386"></a>
-<span class="sourceLineNo">387</span>    }<a name="line.387"></a>
-<span class="sourceLineNo">388</span>    // Remove dead server with same hostname and port of newly checking in rs after master<a name="line.388"></a>
-<span class="sourceLineNo">389</span>    // initialization. See HBASE-5916 for more information.<a name="line.389"></a>
-<span class="sourceLineNo">390</span>    if (<a name="line.390"></a>
-<span class="sourceLineNo">391</span>      (this.master == null || this.master.isInitialized())<a name="line.391"></a>
-<span class="sourceLineNo">392</span>        &amp;&amp; this.deadservers.cleanPreviousInstance(serverName)<a name="line.392"></a>
-<span class="sourceLineNo">393</span>    ) {<a name="line.393"></a>
-<span class="sourceLineNo">394</span>      // This server has now become alive after we marked it as dead.<a name="line.394"></a>
-<span class="sourceLineNo">395</span>      // We removed it's previous entry from the dead list to reflect it.<a name="line.395"></a>
-<span class="sourceLineNo">396</span>      LOG.debug("{} {} came back up, removed it from the dead servers list", what, serverName);<a name="line.396"></a>
-<span class="sourceLineNo">397</span>    }<a name="line.397"></a>
-<span class="sourceLineNo">398</span>  }<a name="line.398"></a>
-<span class="sourceLineNo">399</span><a name="line.399"></a>
-<span class="sourceLineNo">400</span>  /**<a name="line.400"></a>
-<span class="sourceLineNo">401</span>   * Assumes onlineServers is locked.<a name="line.401"></a>
-<span class="sourceLineNo">402</span>   * @return ServerName with matching hostname and port.<a name="line.402"></a>
-<span class="sourceLineNo">403</span>   */<a name="line.403"></a>
-<span class="sourceLineNo">404</span>  private ServerName findServerWithSameHostnamePortWithLock(final ServerName serverName) {<a name="line.404"></a>
-<span class="sourceLineNo">405</span>    ServerName end =<a name="line.405"></a>
-<span class="sourceLineNo">406</span>      ServerName.valueOf(serverName.getHostname(), serverName.getPort(), Long.MAX_VALUE);<a name="line.406"></a>
-<span class="sourceLineNo">407</span><a name="line.407"></a>
-<span class="sourceLineNo">408</span>    ServerName r = onlineServers.lowerKey(end);<a name="line.408"></a>
-<span class="sourceLineNo">409</span>    if (r != null) {<a name="line.409"></a>
-<span class="sourceLineNo">410</span>      if (ServerName.isSameAddress(r, serverName)) {<a name="line.410"></a>
-<span class="sourceLineNo">411</span>        return r;<a name="line.411"></a>
-<span class="sourceLineNo">412</span>      }<a name="line.412"></a>
-<span class="sourceLineNo">413</span>    }<a name="line.413"></a>
-<span class="sourceLineNo">414</span>    return null;<a name="line.414"></a>
-<span class="sourceLineNo">415</span>  }<a name="line.415"></a>
-<span class="sourceLineNo">416</span><a name="line.416"></a>
-<span class="sourceLineNo">417</span>  /**<a name="line.417"></a>
-<span class="sourceLineNo">418</span>   * Adds the onlineServers list. onlineServers should be locked.<a name="line.418"></a>
-<span class="sourceLineNo">419</span>   * @param serverName The remote servers name.<a name="line.419"></a>
-<span class="sourceLineNo">420</span>   */<a name="line.420"></a>
-<span class="sourceLineNo">421</span>  void recordNewServerWithLock(final ServerName serverName, final ServerMetrics sl) {<a name="line.421"></a>
-<span class="sourceLineNo">422</span>    LOG.info("Registering regionserver=" + serverName);<a name="line.422"></a>
-<span class="sourceLineNo">423</span>    this.onlineServers.put(serverName, sl);<a name="line.423"></a>
-<span class="sourceLineNo">424</span>  }<a name="line.424"></a>
-<span class="sourceLineNo">425</span><a name="line.425"></a>
-<span class="sourceLineNo">426</span>  public ConcurrentNavigableMap&lt;byte[], Long&gt; getFlushedSequenceIdByRegion() {<a name="line.426"></a>
-<span class="sourceLineNo">427</span>    return flushedSequenceIdByRegion;<a name="line.427"></a>
-<span class="sourceLineNo">428</span>  }<a name="line.428"></a>
-<span class="sourceLineNo">429</span><a name="line.429"></a>
-<span class="sourceLineNo">430</span>  public RegionStoreSequenceIds getLastFlushedSequenceId(byte[] encodedRegionName) {<a name="line.430"></a>
-<span class="sourceLineNo">431</span>    RegionStoreSequenceIds.Builder builder = RegionStoreSequenceIds.newBuilder();<a name="line.431"></a>
-<span class="sourceLineNo">432</span>    Long seqId = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.432"></a>
-<span class="sourceLineNo">433</span>    builder.setLastFlushedSequenceId(seqId != null ? seqId.longValue() : HConstants.NO_SEQNUM);<a name="line.433"></a>
-<span class="sourceLineNo">434</span>    Map&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.434"></a>
-<span class="sourceLineNo">435</span>      storeFlushedSequenceIdsByRegion.get(encodedRegionName);<a name="line.435"></a>
-<span class="sourceLineNo">436</span>    if (storeFlushedSequenceId != null) {<a name="line.436"></a>
-<span class="sourceLineNo">437</span>      for (Map.Entry&lt;byte[], Long&gt; entry : storeFlushedSequenceId.entrySet()) {<a name="line.437"></a>
-<span class="sourceLineNo">438</span>        builder.addStoreSequenceId(StoreSequenceId.newBuilder()<a name="line.438"></a>
-<span class="sourceLineNo">439</span>          .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey()))<a name="line.439"></a>
-<span class="sourceLineNo">440</span>          .setSequenceId(entry.getValue().longValue()).build());<a name="line.440"></a>
-<span class="sourceLineNo">441</span>      }<a name="line.441"></a>
-<span class="sourceLineNo">442</span>    }<a name="line.442"></a>
-<span class="sourceLineNo">443</span>    return builder.build();<a name="line.443"></a>
-<span class="sourceLineNo">444</span>  }<a name="line.444"></a>
-<span class="sourceLineNo">445</span><a name="line.445"></a>
-<span class="sourceLineNo">446</span>  /**<a name="line.446"></a>
-<span class="sourceLineNo">447</span>   * n * @return ServerMetrics if serverName is known else null<a name="line.447"></a>
-<span class="sourceLineNo">448</span>   */<a name="line.448"></a>
-<span class="sourceLineNo">449</span>  public ServerMetrics getLoad(final ServerName serverName) {<a name="line.449"></a>
-<span class="sourceLineNo">450</span>    return this.onlineServers.get(serverName);<a name="line.450"></a>
-<span class="sourceLineNo">451</span>  }<a name="line.451"></a>
-<span class="sourceLineNo">452</span><a name="line.452"></a>
-<span class="sourceLineNo">453</span>  /**<a name="line.453"></a>
-<span class="sourceLineNo">454</span>   * Compute the average load across all region servers. Currently, this uses a very naive<a name="line.454"></a>
-<span class="sourceLineNo">455</span>   * computation - just uses the number of regions being served, ignoring stats about number of<a name="line.455"></a>
-<span class="sourceLineNo">456</span>   * requests.<a name="line.456"></a>
-<span class="sourceLineNo">457</span>   * @return the average load<a name="line.457"></a>
-<span class="sourceLineNo">458</span>   */<a name="line.458"></a>
-<span class="sourceLineNo">459</span>  public double getAverageLoad() {<a name="line.459"></a>
-<span class="sourceLineNo">460</span>    int totalLoad = 0;<a name="line.460"></a>
-<span class="sourceLineNo">461</span>    int numServers = 0;<a name="line.461"></a>
-<span class="sourceLineNo">462</span>    for (ServerMetrics sl : this.onlineServers.values()) {<a name="line.462"></a>
-<span class="sourceLineNo">463</span>      numServers++;<a name="line.463"></a>
-<span class="sourceLineNo">464</span>      totalLoad += sl.getRegionMetrics().size();<a name="line.464"></a>
-<span class="sourceLineNo">465</span>    }<a name="line.465"></a>
-<span class="sourceLineNo">466</span>    return numServers == 0 ? 0 : (double) totalLoad / (double) numServers;<a name="line.466"></a>
-<span class="sourceLineNo">467</span>  }<a name="line.467"></a>
-<span class="sourceLineNo">468</span><a name="line.468"></a>
-<span class="sourceLineNo">469</span>  /** Returns the count of active regionservers */<a name="line.469"></a>
-<span class="sourceLineNo">470</span>  public int countOfRegionServers() {<a name="line.470"></a>
-<span class="sourceLineNo">471</span>    // Presumes onlineServers is a concurrent map<a name="line.471"></a>
-<span class="sourceLineNo">472</span>    return this.onlineServers.size();<a name="line.472"></a>
-<span class="sourceLineNo">473</span>  }<a name="line.473"></a>
-<span class="sourceLineNo">474</span><a name="line.474"></a>
-<span class="sourceLineNo">475</span>  /** Returns Read-only map of servers to serverinfo */<a name="line.475"></a>
-<span class="sourceLineNo">476</span>  public Map&lt;ServerName, ServerMetrics&gt; getOnlineServers() {<a name="line.476"></a>
-<span class="sourceLineNo">477</span>    // Presumption is that iterating the returned Map is OK.<a name="line.477"></a>
-<span class="sourceLineNo">478</span>    synchronized (this.onlineServers) {<a name="line.478"></a>
-<span class="sourceLineNo">479</span>      return Collections.unmodifiableMap(this.onlineServers);<a name="line.479"></a>
-<span class="sourceLineNo">480</span>    }<a name="line.480"></a>
-<span class="sourceLineNo">481</span>  }<a name="line.481"></a>
-<span class="sourceLineNo">482</span><a name="line.482"></a>
-<span class="sourceLineNo">483</span>  public DeadServer getDeadServers() {<a name="line.483"></a>
-<span class="sourceLineNo">484</span>    return this.deadservers;<a name="line.484"></a>
-<span class="sourceLineNo">485</span>  }<a name="line.485"></a>
-<span class="sourceLineNo">486</span><a name="line.486"></a>
-<span class="sourceLineNo">487</span>  /**<a name="line.487"></a>
-<span class="sourceLineNo">488</span>   * Checks if any dead servers are currently in progress.<a name="line.488"></a>
-<span class="sourceLineNo">489</span>   * @return true if any RS are being processed as dead, false if not<a name="line.489"></a>
-<span class="sourceLineNo">490</span>   */<a name="line.490"></a>
-<span class="sourceLineNo">491</span>  public boolean areDeadServersInProgress() throws IOException {<a name="line.491"></a>
-<span class="sourceLineNo">492</span>    return master.getProcedures().stream()<a name="line.492"></a>
-<span class="sourceLineNo">493</span>      .anyMatch(p -&gt; !p.isFinished() &amp;&amp; p instanceof ServerCrashProcedure);<a name="line.493"></a>
-<span class="sourceLineNo">494</span>  }<a name="line.494"></a>
-<span class="sourceLineNo">495</span><a name="line.495"></a>
-<span class="sourceLineNo">496</span>  void letRegionServersShutdown() {<a name="line.496"></a>
-<span class="sourceLineNo">497</span>    long previousLogTime = 0;<a name="line.497"></a>
-<span class="sourceLineNo">498</span>    ServerName sn = master.getServerName();<a name="line.498"></a>
-<span class="sourceLineNo">499</span>    ZKWatcher zkw = master.getZooKeeper();<a name="line.499"></a>
-<span class="sourceLineNo">500</span>    int onlineServersCt;<a name="line.500"></a>
-<span class="sourceLineNo">501</span>    while ((onlineServersCt = onlineServers.size()) &gt; 0) {<a name="line.501"></a>
-<span class="sourceLineNo">502</span>      if (EnvironmentEdgeManager.currentTime() &gt; (previousLogTime + 1000)) {<a name="line.502"></a>
-<span class="sourceLineNo">503</span>        Set&lt;ServerName&gt; remainingServers = onlineServers.keySet();<a name="line.503"></a>
-<span class="sourceLineNo">504</span>        synchronized (onlineServers) {<a name="line.504"></a>
-<span class="sourceLineNo">505</span>          if (remainingServers.size() == 1 &amp;&amp; remainingServers.contains(sn)) {<a name="line.505"></a>
-<span class="sourceLineNo">506</span>            // Master will delete itself later.<a name="line.506"></a>
-<span class="sourceLineNo">507</span>            return;<a name="line.507"></a>
-<span class="sourceLineNo">508</span>          }<a name="line.508"></a>
-<span class="sourceLineNo">509</span>        }<a name="line.509"></a>
-<span class="sourceLineNo">510</span>        StringBuilder sb = new StringBuilder();<a name="line.510"></a>
-<span class="sourceLineNo">511</span>        // It's ok here to not sync on onlineServers - merely logging<a name="line.511"></a>
-<span class="sourceLineNo">512</span>        for (ServerName key : remainingServers) {<a name="line.512"></a>
-<span class="sourceLineNo">513</span>          if (sb.length() &gt; 0) {<a name="line.513"></a>
-<span class="sourceLineNo">514</span>            sb.append(", ");<a name="line.514"></a>
-<span class="sourceLineNo">515</span>          }<a name="line.515"></a>
-<span class="sourceLineNo">516</span>          sb.append(key);<a name="line.516"></a>
-<span class="sourceLineNo">517</span>        }<a name="line.517"></a>
-<span class="sourceLineNo">518</span>        LOG.info("Waiting on regionserver(s) " + sb.toString());<a name="line.518"></a>
-<span class="sourceLineNo">519</span>        previousLogTime = EnvironmentEdgeManager.currentTime();<a name="line.519"></a>
-<span class="sourceLineNo">520</span>      }<a name="line.520"></a>
-<span class="sourceLineNo">521</span><a name="line.521"></a>
-<span class="sourceLineNo">522</span>      try {<a name="line.522"></a>
-<span class="sourceLineNo">523</span>        List&lt;String&gt; servers = getRegionServersInZK(zkw);<a name="line.523"></a>
-<span class="sourceLineNo">524</span>        if (<a name="line.524"></a>
-<span class="sourceLineNo">525</span>          servers == null || servers.isEmpty()<a name="line.525"></a>
-<span class="sourceLineNo">526</span>            || (servers.size() == 1 &amp;&amp; servers.contains(sn.toString()))<a name="line.526"></a>
-<span class="sourceLineNo">527</span>        ) {<a name="line.527"></a>
-<span class="sourceLineNo">528</span>          LOG.info("ZK shows there is only the master self online, exiting now");<a name="line.528"></a>
-<span class="sourceLineNo">529</span>          // Master could have lost some ZK events, no need to wait more.<a name="line.529"></a>
-<span class="sourceLineNo">530</span>          break;<a name="line.530"></a>
-<span class="sourceLineNo">531</span>        }<a name="line.531"></a>
-<span class="sourceLineNo">532</span>      } catch (KeeperException ke) {<a name="line.532"></a>
-<span class="sourceLineNo">533</span>        LOG.warn("Failed to list regionservers", ke);<a name="line.533"></a>
-<span class="sourceLineNo">534</span>        // ZK is malfunctioning, don't hang here<a name="line.534"></a>
-<span class="sourceLineNo">535</span>        break;<a name="line.535"></a>
-<span class="sourceLineNo">536</span>      }<a name="line.536"></a>
-<span class="sourceLineNo">537</span>      synchronized (onlineServers) {<a name="line.537"></a>
-<span class="sourceLineNo">538</span>        try {<a name="line.538"></a>
-<span class="sourceLineNo">539</span>          if (onlineServersCt == onlineServers.size()) onlineServers.wait(100);<a name="line.539"></a>
-<span class="sourceLineNo">540</span>        } catch (InterruptedException ignored) {<a name="line.540"></a>
-<span class="sourceLineNo">541</span>          // continue<a name="line.541"></a>
-<span class="sourceLineNo">542</span>        }<a name="line.542"></a>
-<span class="sourceLineNo">543</span>      }<a name="line.543"></a>
-<span class="sourceLineNo">544</span>    }<a name="line.544"></a>
-<span class="sourceLineNo">545</span>  }<a name="line.545"></a>
-<span class="sourceLineNo">546</span><a name="line.546"></a>
-<span class="sourceLineNo">547</span>  private List&lt;String&gt; getRegionServersInZK(final ZKWatcher zkw) throws KeeperException {<a name="line.547"></a>
-<span class="sourceLineNo">548</span>    return ZKUtil.listChildrenNoWatch(zkw, zkw.getZNodePaths().rsZNode);<a name="line.548"></a>
-<span class="sourceLineNo">549</span>  }<a name="line.549"></a>
-<span class="sourceLineNo">550</span><a name="line.550"></a>
-<span class="sourceLineNo">551</span>  /**<a name="line.551"></a>
-<span class="sourceLineNo">552</span>   * Expire the passed server. Add it to list of dead servers and queue a shutdown processing.<a name="line.552"></a>
-<span class="sourceLineNo">553</span>   * @return pid if we queued a ServerCrashProcedure else {@link Procedure#NO_PROC_ID} if we did not<a name="line.553"></a>
-<span class="sourceLineNo">554</span>   *         (could happen for many reasons including the fact that its this server that is going<a name="line.554"></a>
-<span class="sourceLineNo">555</span>   *         down or we already have queued an SCP for this server or SCP processing is currently<a name="line.555"></a>
-<span class="sourceLineNo">556</span>   *         disabled because we are in startup phase).<a name="line.556"></a>
-<span class="sourceLineNo">557</span>   */<a name="line.557"></a>
-<span class="sourceLineNo">558</span>  // Redo test so we can make this protected.<a name="line.558"></a>
-<span class="sourceLineNo">559</span>  public synchronized long expireServer(final ServerName serverName) {<a name="line.559"></a>
-<span class="sourceLineNo">560</span>    return expireServer(serverName, false);<a name="line.560"></a>
-<span class="sourceLineNo">561</span><a name="line.561"></a>
-<span class="sourceLineNo">562</span>  }<a name="line.562"></a>
-<span class="sourceLineNo">563</span><a name="line.563"></a>
-<span class="sourceLineNo">564</span>  synchronized long expireServer(final ServerName serverName, boolean force) {<a name="line.564"></a>
-<span class="sourceLineNo">565</span>    // THIS server is going down... can't handle our own expiration.<a name="line.565"></a>
-<span class="sourceLineNo">566</span>    if (serverName.equals(master.getServerName())) {<a name="line.566"></a>
-<span class="sourceLineNo">567</span>      if (!(master.isAborted() || master.isStopped())) {<a name="line.567"></a>
-<span class="sourceLineNo">568</span>        master.stop("We lost our znode?");<a name="line.568"></a>
-<span class="sourceLineNo">569</span>      }<a name="line.569"></a>
-<span class="sourceLineNo">570</span>      return Procedure.NO_PROC_ID;<a name="line.570"></a>
-<span class="sourceLineNo">571</span>    }<a name="line.571"></a>
-<span class="sourceLineNo">572</span>    if (this.deadservers.isDeadServer(serverName)) {<a name="line.572"></a>
-<span class="sourceLineNo">573</span>      LOG.warn("Expiration called on {} but already in DeadServer", serverName);<a name="line.573"></a>
-<span class="sourceLineNo">574</span>      return Procedure.NO_PROC_ID;<a name="line.574"></a>
-<span class="sourceLineNo">575</span>    }<a name="line.575"></a>
-<span class="sourceLineNo">576</span>    moveFromOnlineToDeadServers(serverName);<a name="line.576"></a>
-<span class="sourceLineNo">577</span><a name="line.577"></a>
-<span class="sourceLineNo">578</span>    // If server is in draining mode, remove corresponding znode<a name="line.578"></a>
-<span class="sourceLineNo">579</span>    // In some tests, the mocked HM may not have ZK Instance, hence null check<a name="line.579"></a>
-<span class="sourceLineNo">580</span>    if (master.getZooKeeper() != null) {<a name="line.580"></a>
-<span class="sourceLineNo">581</span>      String drainingZnode = ZNodePaths<a name="line.581"></a>
-<span class="sourceLineNo">582</span>        .joinZNode(master.getZooKeeper().getZNodePaths().drainingZNode, serverName.getServerName());<a name="line.582"></a>
-<span class="sourceLineNo">583</span>      try {<a name="line.583"></a>
-<span class="sourceLineNo">584</span>        ZKUtil.deleteNodeFailSilent(master.getZooKeeper(), drainingZnode);<a name="line.584"></a>
-<span class="sourceLineNo">585</span>      } catch (KeeperException e) {<a name="line.585"></a>
-<span class="sourceLineNo">586</span>        LOG.warn(<a name="line.586"></a>
-<span class="sourceLineNo">587</span>          "Error deleting the draining znode for stopping server " + serverName.getServerName(), e);<a name="line.587"></a>
-<span class="sourceLineNo">588</span>      }<a name="line.588"></a>
-<span class="sourceLineNo">589</span>    }<a name="line.589"></a>
-<span class="sourceLineNo">590</span><a name="line.590"></a>
-<span class="sourceLineNo">591</span>    // If cluster is going down, yes, servers are going to be expiring; don't<a name="line.591"></a>
-<span class="sourceLineNo">592</span>    // process as a dead server<a name="line.592"></a>
-<span class="sourceLineNo">593</span>    if (isClusterShutdown()) {<a name="line.593"></a>
-<span class="sourceLineNo">594</span>      LOG.info("Cluster shutdown set; " + serverName + " expired; onlineServers="<a name="line.594"></a>
-<span class="sourceLineNo">595</span>        + this.onlineServers.size());<a name="line.595"></a>
-<span class="sourceLineNo">596</span>      if (this.onlineServers.isEmpty()) {<a name="line.596"></a>
-<span class="sourceLineNo">597</span>        master.stop("Cluster shutdown set; onlineServer=0");<a name="line.597"></a>
-<span class="sourceLineNo">598</span>      }<a name="line.598"></a>
-<span class="sourceLineNo">599</span>      return Procedure.NO_PROC_ID;<a name="line.599"></a>
-<span class="sourceLineNo">600</span>    }<a name="line.600"></a>
-<span class="sourceLineNo">601</span>    LOG.info("Processing expiration of " + serverName + " on " + this.master.getServerName());<a name="line.601"></a>
-<span class="sourceLineNo">602</span>    long pid = master.getAssignmentManager().submitServerCrash(serverName, true, force);<a name="line.602"></a>
-<span class="sourceLineNo">603</span>    storage.expired(serverName);<a name="line.603"></a>
-<span class="sourceLineNo">604</span>    // Tell our listeners that a server was removed<a name="line.604"></a>
-<span class="sourceLineNo">605</span>    if (!this.listeners.isEmpty()) {<a name="line.605"></a>
-<span class="sourceLineNo">606</span>      this.listeners.stream().forEach(l -&gt; l.serverRemoved(serverName));<a name="line.606"></a>
-<span class="sourceLineNo">607</span>    }<a name="line.607"></a>
-<span class="sourceLineNo">608</span>    // trigger a persist of flushedSeqId<a name="line.608"></a>
-<span class="sourceLineNo">609</span>    if (flushedSeqIdFlusher != null) {<a name="line.609"></a>
-<span class="sourceLineNo">610</span>      flushedSeqIdFlusher.triggerNow();<a name="line.610"></a>
-<span class="sourceLineNo">611</span>    }<a name="line.611"></a>
-<span class="sourceLineNo">612</span>    return pid;<a name="line.612"></a>
-<span class="sourceLineNo">613</span>  }<a name="line.613"></a>
-<span class="sourceLineNo">614</span><a name="line.614"></a>
-<span class="sourceLineNo">615</span>  /**<a name="line.615"></a>
-<span class="sourceLineNo">616</span>   * Called when server has expired.<a name="line.616"></a>
-<span class="sourceLineNo">617</span>   */<a name="line.617"></a>
-<span class="sourceLineNo">618</span>  // Locking in this class needs cleanup.<a name="line.618"></a>
-<span class="sourceLineNo">619</span>  public synchronized void moveFromOnlineToDeadServers(final ServerName sn) {<a name="line.619"></a>
-<span class="sourceLineNo">620</span>    synchronized (this.onlineServers) {<a name="line.620"></a>
-<span class="sourceLineNo">621</span>      boolean online = this.onlineServers.containsKey(sn);<a name="line.621"></a>
-<span class="sourceLineNo">622</span>      if (online) {<a name="line.622"></a>
-<span class="sourceLineNo">623</span>        // Remove the server from the known servers lists and update load info BUT<a name="line.623"></a>
-<span class="sourceLineNo">624</span>        // add to deadservers first; do this so it'll show in dead servers list if<a name="line.624"></a>
-<span class="sourceLineNo">625</span>        // not in online servers list.<a name="line.625"></a>
-<span class="sourceLineNo">626</span>        this.deadservers.putIfAbsent(sn);<a name="line.626"></a>
-<span class="sourceLineNo">627</span>        this.onlineServers.remove(sn);<a name="line.627"></a>
-<span class="sourceLineNo">628</span>        onlineServers.notifyAll();<a name="line.628"></a>
-<span class="sourceLineNo">629</span>      } else {<a name="line.629"></a>
-<span class="sourceLineNo">630</span>        // If not online, that is odd but may happen if 'Unknown Servers' -- where meta<a name="line.630"></a>
-<span class="sourceLineNo">631</span>        // has references to servers not online nor in dead servers list. If<a name="line.631"></a>
-<span class="sourceLineNo">632</span>        // 'Unknown Server', don't add to DeadServers else will be there for ever.<a name="line.632"></a>
-<span class="sourceLineNo">633</span>        LOG.trace("Expiration of {} but server not online", sn);<a name="line.633"></a>
-<span class="sourceLineNo">634</span>      }<a name="line.634"></a>
-<span class="sourceLineNo">635</span>    }<a name="line.635"></a>
-<span class="sourceLineNo">636</span>  }<a name="line.636"></a>
-<span class="sourceLineNo">637</span><a name="line.637"></a>
-<span class="sourceLineNo">638</span>  /*<a name="line.638"></a>
-<span class="sourceLineNo">639</span>   * Remove the server from the drain list.<a name="line.639"></a>
-<span class="sourceLineNo">640</span>   */<a name="line.640"></a>
-<span class="sourceLineNo">641</span>  public synchronized boolean removeServerFromDrainList(final ServerName sn) {<a name="line.641"></a>
-<span class="sourceLineNo">642</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.642"></a>
-<span class="sourceLineNo">643</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.643"></a>
-<span class="sourceLineNo">644</span><a name="line.644"></a>
-<span class="sourceLineNo">645</span>    if (!this.isServerOnline(sn)) {<a name="line.645"></a>
-<span class="sourceLineNo">646</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.646"></a>
-<span class="sourceLineNo">647</span>        + "Removing from draining list anyway, as requested.");<a name="line.647"></a>
-<span class="sourceLineNo">648</span>    }<a name="line.648"></a>
-<span class="sourceLineNo">649</span>    // Remove the server from the draining servers lists.<a name="line.649"></a>
-<span class="sourceLineNo">650</span>    return this.drainingServers.remove(sn);<a name="line.650"></a>
-<span class="sourceLineNo">651</span>  }<a name="line.651"></a>
-<span class="sourceLineNo">652</span><a name="line.652"></a>
-<span class="sourceLineNo">653</span>  /**<a name="line.653"></a>
-<span class="sourceLineNo">654</span>   * Add the server to the drain list. n * @return True if the server is added or the server is<a name="line.654"></a>
-<span class="sourceLineNo">655</span>   * already on the drain list.<a name="line.655"></a>
-<span class="sourceLineNo">656</span>   */<a name="line.656"></a>
-<span class="sourceLineNo">657</span>  public synchronized boolean addServerToDrainList(final ServerName sn) {<a name="line.657"></a>
-<span class="sourceLineNo">658</span>    // Warn if the server (sn) is not online. ServerName is of the form:<a name="line.658"></a>
-<span class="sourceLineNo">659</span>    // &lt;hostname&gt; , &lt;port&gt; , &lt;startcode&gt;<a name="line.659"></a>
-<span class="sourceLineNo">660</span><a name="line.660"></a>
-<span class="sourceLineNo">661</span>    if (!this.isServerOnline(sn)) {<a name="line.661"></a>
-<span class="sourceLineNo">662</span>      LOG.warn("Server " + sn + " is not currently online. "<a name="line.662"></a>
-<span class="sourceLineNo">663</span>        + "Ignoring request to add it to draining list.");<a name="line.663"></a>
-<span class="sourceLineNo">664</span>      return false;<a name="line.664"></a>
-<span class="sourceLineNo">665</span>    }<a name="line.665"></a>
-<span class="sourceLineNo">666</span>    // Add the server to the draining servers lists, if it's not already in<a name="line.666"></a>
-<span class="sourceLineNo">667</span>    // it.<a name="line.667"></a>
-<span class="sourceLineNo">668</span>    if (this.drainingServers.contains(sn)) {<a name="line.668"></a>
-<span class="sourceLineNo">669</span>      LOG.warn("Server " + sn + " is already in the draining server list."<a name="line.669"></a>
-<span class="sourceLineNo">670</span>        + "Ignoring request to add it again.");<a name="line.670"></a>
-<span class="sourceLineNo">671</span>      return true;<a name="line.671"></a>
-<span class="sourceLineNo">672</span>    }<a name="line.672"></a>
-<span class="sourceLineNo">673</span>    LOG.info("Server " + sn + " added to draining server list.");<a name="line.673"></a>
-<span class="sourceLineNo">674</span>    return this.drainingServers.add(sn);<a name="line.674"></a>
-<span class="sourceLineNo">675</span>  }<a name="line.675"></a>
-<span class="sourceLineNo">676</span><a name="line.676"></a>
-<span class="sourceLineNo">677</span>  /**<a name="line.677"></a>
-<span class="sourceLineNo">678</span>   * Contacts a region server and waits up to timeout ms to close the region. This bypasses the<a name="line.678"></a>
-<span class="sourceLineNo">679</span>   * active hmaster. Pass -1 as timeout if you do not want to wait on result.<a name="line.679"></a>
-<span class="sourceLineNo">680</span>   */<a name="line.680"></a>
-<span class="sourceLineNo">681</span>  public static void closeRegionSilentlyAndWait(AsyncClusterConnection connection,<a name="line.681"></a>
-<span class="sourceLineNo">682</span>    ServerName server, RegionInfo region, long timeout) throws IOException, InterruptedException {<a name="line.682"></a>
-<span class="sourceLineNo">683</span>    AsyncRegionServerAdmin admin = connection.getRegionServerAdmin(server);<a name="line.683"></a>
-<span class="sourceLineNo">684</span>    try {<a name="line.684"></a>
-<span class="sourceLineNo">685</span>      FutureUtils.get(<a name="line.685"></a>
-<span class="sourceLineNo">686</span>        admin.closeRegion(ProtobufUtil.buildCloseRegionRequest(server, region.getRegionName())));<a name="line.686"></a>
-<span class="sourceLineNo">687</span>    } catch (IOException e) {<a name="line.687"></a>
-<span class="sourceLineNo">688</span>      LOG.warn("Exception when closing region: " + region.getRegionNameAsString(), e);<a name="line.688"></a>
-<span class="sourceLineNo">689</span>    }<a name="line.689"></a>
-<span class="sourceLineNo">690</span>    if (timeout &lt; 0) {<a name="line.690"></a>
-<span class="sourceLineNo">691</span>      return;<a name="line.691"></a>
-<span class="sourceLineNo">692</span>    }<a name="line.692"></a>
-<span class="sourceLineNo">693</span>    long expiration = timeout + EnvironmentEdgeManager.currentTime();<a name="line.693"></a>
-<span class="sourceLineNo">694</span>    while (EnvironmentEdgeManager.currentTime() &lt; expiration) {<a name="line.694"></a>
-<span class="sourceLineNo">695</span>      try {<a name="line.695"></a>
-<span class="sourceLineNo">696</span>        RegionInfo rsRegion = ProtobufUtil.toRegionInfo(FutureUtils<a name="line.696"></a>
-<span class="sourceLineNo">697</span>          .get(<a name="line.697"></a>
-<span class="sourceLineNo">698</span>            admin.getRegionInfo(RequestConverter.buildGetRegionInfoRequest(region.getRegionName())))<a name="line.698"></a>
-<span class="sourceLineNo">699</span>          .getRegionInfo());<a name="line.699"></a>
-<span class="sourceLineNo">700</span>        if (rsRegion == null) {<a name="line.700"></a>
-<span class="sourceLineNo">701</span>          return;<a name="line.701"></a>
-<span class="sourceLineNo">702</span>        }<a name="line.702"></a>
-<span class="sourceLineNo">703</span>      } catch (IOException ioe) {<a name="line.703"></a>
-<span class="sourceLineNo">704</span>        if (<a name="line.704"></a>
-<span class="sourceLineNo">705</span>          ioe instanceof NotServingRegionException<a name="line.705"></a>
-<span class="sourceLineNo">706</span>            || (ioe instanceof RemoteWithExtrasException &amp;&amp; ((RemoteWithExtrasException) ioe)<a name="line.706"></a>
-<span class="sourceLineNo">707</span>              .unwrapRemoteException() instanceof NotServingRegionException)<a name="line.707"></a>
-<span class="sourceLineNo">708</span>        ) {<a name="line.708"></a>
-<span class="sourceLineNo">709</span>          // no need to retry again<a name="line.709"></a>
-<span class="sourceLineNo">710</span>          return;<a name="line.710"></a>
-<span class="sourceLineNo">711</span>        }<a name="line.711"></a>
-<span class="sourceLineNo">712</span>        LOG.warn("Exception when retrieving regioninfo from: " + region.getRegionNameAsString(),<a name="line.712"></a>
-<span class="sourceLineNo">713</span>          ioe);<a name="line.713"></a>
-<span class="sourceLineNo">714</span>      }<a name="line.714"></a>
-<span class="sourceLineNo">715</span>      Thread.sleep(1000);<a name="line.715"></a>
-<span class="sourceLineNo">716</span>    }<a name="line.716"></a>
-<span class="sourceLineNo">717</span>    throw new IOException("Region " + region + " failed to close within" + " timeout " + timeout);<a name="line.717"></a>
-<span class="sourceLineNo">718</span>  }<a name="line.718"></a>
-<span class="sourceLineNo">719</span><a name="line.719"></a>
-<span class="sourceLineNo">720</span>  /**<a name="line.720"></a>
-<span class="sourceLineNo">721</span>   * Calculate min necessary to start. This is not an absolute. It is just a friction that will<a name="line.721"></a>
-<span class="sourceLineNo">722</span>   * cause us hang around a bit longer waiting on RegionServers to check-in.<a name="line.722"></a>
-<span class="sourceLineNo">723</span>   */<a name="line.723"></a>
-<span class="sourceLineNo">724</span>  private int getMinToStart() {<a name="line.724"></a>
-<span class="sourceLineNo">725</span>    if (master.isInMaintenanceMode()) {<a name="line.725"></a>
-<span class="sourceLineNo">726</span>      // If in maintenance mode, then in process region server hosting meta will be the only server<a name="line.726"></a>
-<span class="sourceLineNo">727</span>      // available<a name="line.727"></a>
-<span class="sourceLineNo">728</span>      return 1;<a name="line.728"></a>
-<span class="sourceLineNo">729</span>    }<a name="line.729"></a>
-<span class="sourceLineNo">730</span><a name="line.730"></a>
-<span class="sourceLineNo">731</span>    int minimumRequired = 1;<a name="line.731"></a>
-<span class="sourceLineNo">732</span>    int minToStart = this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MINTOSTART, -1);<a name="line.732"></a>
-<span class="sourceLineNo">733</span>    // Ensure we are never less than minimumRequired else stuff won't work.<a name="line.733"></a>
-<span class="sourceLineNo">734</span>    return Math.max(minToStart, minimumRequired);<a name="line.734"></a>
-<span class="sourceLineNo">735</span>  }<a name="line.735"></a>
-<span class="sourceLineNo">736</span><a name="line.736"></a>
-<span class="sourceLineNo">737</span>  /**<a name="line.737"></a>
-<span class="sourceLineNo">738</span>   * Wait for the region servers to report in. We will wait until one of this condition is met: -<a name="line.738"></a>
-<span class="sourceLineNo">739</span>   * the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region<a name="line.739"></a>
-<span class="sourceLineNo">740</span>   * servers is reached - the 'hbase.master.wait.on.regionservers.mintostart' is reached AND there<a name="line.740"></a>
-<span class="sourceLineNo">741</span>   * have been no new region server in for 'hbase.master.wait.on.regionservers.interval' time AND<a name="line.741"></a>
-<span class="sourceLineNo">742</span>   * the 'hbase.master.wait.on.regionservers.timeout' is reached n<a name="line.742"></a>
-<span class="sourceLineNo">743</span>   */<a name="line.743"></a>
-<span class="sourceLineNo">744</span>  public void waitForRegionServers(MonitoredTask status) throws InterruptedException {<a name="line.744"></a>
-<span class="sourceLineNo">745</span>    final long interval =<a name="line.745"></a>
-<span class="sourceLineNo">746</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_INTERVAL, 1500);<a name="line.746"></a>
-<span class="sourceLineNo">747</span>    final long timeout =<a name="line.747"></a>
-<span class="sourceLineNo">748</span>      this.master.getConfiguration().getLong(WAIT_ON_REGIONSERVERS_TIMEOUT, 4500);<a name="line.748"></a>
-<span class="sourceLineNo">749</span>    // Min is not an absolute; just a friction making us wait longer on server checkin.<a name="line.749"></a>
-<span class="sourceLineNo">750</span>    int minToStart = getMinToStart();<a name="line.750"></a>
-<span class="sourceLineNo">751</span>    int maxToStart =<a name="line.751"></a>
-<span class="sourceLineNo">752</span>      this.master.getConfiguration().getInt(WAIT_ON_REGIONSERVERS_MAXTOSTART, Integer.MAX_VALUE);<a name="line.752"></a>
-<span class="sourceLineNo">753</span>    if (maxToStart &lt; minToStart) {<a name="line.753"></a>
-<span class="sourceLineNo">754</span>      LOG.warn(String.format("The value of '%s' (%d) is set less than '%s' (%d), ignoring.",<a name="line.754"></a>
-<span class="sourceLineNo">755</span>        WAIT_ON_REGIONSERVERS_MAXTOSTART, maxToStart, WAIT_ON_REGIONSERVERS_MINTOSTART,<a name="line.755"></a>
-<span class="sourceLineNo">756</span>        minToStart));<a name="line.756"></a>
-<span class="sourceLineNo">757</span>      maxToStart = Integer.MAX_VALUE;<a name="line.757"></a>
-<span class="sourceLineNo">758</span>    }<a name="line.758"></a>
-<span class="sourceLineNo">759</span><a name="line.759"></a>
-<span class="sourceLineNo">760</span>    long now = EnvironmentEdgeManager.currentTime();<a name="line.760"></a>
-<span class="sourceLineNo">761</span>    final long startTime = now;<a name="line.761"></a>
-<span class="sourceLineNo">762</span>    long slept = 0;<a name="line.762"></a>
-<span class="sourceLineNo">763</span>    long lastLogTime = 0;<a name="line.763"></a>
-<span class="sourceLineNo">764</span>    long lastCountChange = startTime;<a name="line.764"></a>
-<span class="sourceLineNo">765</span>    int count = countOfRegionServers();<a name="line.765"></a>
-<span class="sourceLineNo">766</span>    int oldCount = 0;<a name="line.766"></a>
-<span class="sourceLineNo">767</span>    // This while test is a little hard to read. We try to comment it in below but in essence:<a name="line.767"></a>
-<span class="sourceLineNo">768</span>    // Wait if Master is not stopped and the number of regionservers that have checked-in is<a name="line.768"></a>
-<span class="sourceLineNo">769</span>    // less than the maxToStart. Both of these conditions will be true near universally.<a name="line.769"></a>
-<span class="sourceLineNo">770</span>    // Next, we will keep cycling if ANY of the following three conditions are true:<a name="line.770"></a>
-<span class="sourceLineNo">771</span>    // 1. The time since a regionserver registered is &lt; interval (means servers are actively<a name="line.771"></a>
-<span class="sourceLineNo">772</span>    // checking in).<a name="line.772"></a>
-<span class="sourceLineNo">773</span>    // 2. We are under the total timeout.<a name="line.773"></a>
-<span class="sourceLineNo">774</span>    // 3. The count of servers is &lt; minimum.<a name="line.774"></a>
-<span class="sourceLineNo">775</span>    for (ServerListener listener : this.listeners) {<a name="line.775"></a>
-<span class="sourceLineNo">776</span>      listener.waiting();<a name="line.776"></a>
-<span class="sourceLineNo">777</span>    }<a name="line.777"></a>
-<span class="sourceLineNo">778</span>    while (<a name="line.778"></a>
-<span class="sourceLineNo">779</span>      !this.master.isStopped() &amp;&amp; !isClusterShutdown() &amp;&amp; count &lt; maxToStart<a name="line.779"></a>
-<span class="sourceLineNo">780</span>        &amp;&amp; ((lastCountChange + interval) &gt; now || timeout &gt; slept || count &lt; minToStart)<a name="line.780"></a>
-<span class="sourceLineNo">781</span>    ) {<a name="line.781"></a>
-<span class="sourceLineNo">782</span>      // Log some info at every interval time or if there is a change<a name="line.782"></a>
-<span class="sourceLineNo">783</span>      if (oldCount != count || lastLogTime + interval &lt; now) {<a name="line.783"></a>
-<span class="sourceLineNo">784</span>        lastLogTime = now;<a name="line.784"></a>
-<span class="sourceLineNo">785</span>        String msg =<a name="line.785"></a>
-<span class="sourceLineNo">786</span>          "Waiting on regionserver count=" + count + "; waited=" + slept + "ms, expecting min="<a name="line.786"></a>
-<span class="sourceLineNo">787</span>            + minToStart + " server(s), max=" + getStrForMax(maxToStart) + " server(s), "<a name="line.787"></a>
-<span class="sourceLineNo">788</span>            + "timeout=" + timeout + "ms, lastChange=" + (now - lastCountChange) + "ms";<a name="line.788"></a>
-<span class="sourceLineNo">789</span>        LOG.info(msg);<a name="line.789"></a>
-<span class="sourceLineNo">790</span>        status.setStatus(msg);<a name="line.790"></a>
-<span class="sourceLineNo">791</span>      }<a name="line.791"></a>
-<span class="sourceLineNo">792</span><a name="line.792"></a>
-<span class="sourceLineNo">793</span>      // We sleep for some time<a name="line.793"></a>
-<span class="sourceLineNo">794</span>      final long sleepTime = 50;<a name="line.794"></a>
-<span class="sourceLineNo">795</span>      Thread.sleep(sleepTime);<a name="line.795"></a>
-<span class="sourceLineNo">796</span>      now = EnvironmentEdgeManager.currentTime();<a name="line.796"></a>
-<span class="sourceLineNo">797</span>      slept = now - startTime;<a name="line.797"></a>
-<span class="sourceLineNo">798</span><a name="line.798"></a>
-<span class="sourceLineNo">799</span>      oldCount = count;<a name="line.799"></a>
-<span class="sourceLineNo">800</span>      count = countOfRegionServers();<a name="line.800"></a>
-<span class="sourceLineNo">801</span>      if (count != oldCount) {<a name="line.801"></a>
-<span class="sourceLineNo">802</span>        lastCountChange = now;<a name="line.802"></a>
-<span class="sourceLineNo">803</span>      }<a name="line.803"></a>
-<span class="sourceLineNo">804</span>    }<a name="line.804"></a>
-<span class="sourceLineNo">805</span>    // Did we exit the loop because cluster is going down?<a name="line.805"></a>
-<span class="sourceLineNo">806</span>    if (isClusterShutdown()) {<a name="line.806"></a>
-<span class="sourceLineNo">807</span>      this.master.stop("Cluster shutdown");<a name="line.807"></a>
-<span class="sourceLineNo">808</span>    }<a name="line.808"></a>
-<span class="sourceLineNo">809</span>    LOG.info("Finished waiting on RegionServer count=" + count + "; waited=" + slept + "ms,"<a name="line.809"></a>
-<span class="sourceLineNo">810</span>      + " expected min=" + minToStart + " server(s), max=" + getStrForMax(maxToStart)<a name="line.810"></a>
-<span class="sourceLineNo">811</span>      + " server(s)," + " master is " + (this.master.isStopped() ? "stopped." : "running"));<a name="line.811"></a>
-<span class="sourceLineNo">812</span>  }<a name="line.812"></a>
-<span class="sourceLineNo">813</span><a name="line.813"></a>
-<span class="sourceLineNo">814</span>  private String getStrForMax(final int max) {<a name="line.814"></a>
-<span class="sourceLineNo">815</span>    return max == Integer.MAX_VALUE ? "NO_LIMIT" : Integer.toString(max);<a name="line.815"></a>
-<span class="sourceLineNo">816</span>  }<a name="line.816"></a>
-<span class="sourceLineNo">817</span><a name="line.817"></a>
-<span class="sourceLineNo">818</span>  /** Returns A copy of the internal list of online servers. */<a name="line.818"></a>
-<span class="sourceLineNo">819</span>  public List&lt;ServerName&gt; getOnlineServersList() {<a name="line.819"></a>
-<span class="sourceLineNo">820</span>    // TODO: optimize the load balancer call so we don't need to make a new list<a name="line.820"></a>
-<span class="sourceLineNo">821</span>    // TODO: FIX. THIS IS POPULAR CALL.<a name="line.821"></a>
-<span class="sourceLineNo">822</span>    return new ArrayList&lt;&gt;(this.onlineServers.keySet());<a name="line.822"></a>
-<span class="sourceLineNo">823</span>  }<a name="line.823"></a>
-<span class="sourceLineNo">824</span><a name="line.824"></a>
-<span class="sourceLineNo">825</span>  /**<a name="line.825"></a>
-<span class="sourceLineNo">826</span>   * @param keys                 The target server name<a name="line.826"></a>
-<span class="sourceLineNo">827</span>   * @param idleServerPredicator Evaluates the server on the given load<a name="line.827"></a>
-<span class="sourceLineNo">828</span>   * @return A copy of the internal list of online servers matched by the predicator<a name="line.828"></a>
-<span class="sourceLineNo">829</span>   */<a name="line.829"></a>
-<span class="sourceLineNo">830</span>  public List&lt;ServerName&gt; getOnlineServersListWithPredicator(List&lt;ServerName&gt; keys,<a name="line.830"></a>
-<span class="sourceLineNo">831</span>    Predicate&lt;ServerMetrics&gt; idleServerPredicator) {<a name="line.831"></a>
-<span class="sourceLineNo">832</span>    List&lt;ServerName&gt; names = new ArrayList&lt;&gt;();<a name="line.832"></a>
-<span class="sourceLineNo">833</span>    if (keys != null &amp;&amp; idleServerPredicator != null) {<a name="line.833"></a>
-<span class="sourceLineNo">834</span>      keys.forEach(name -&gt; {<a name="line.834"></a>
-<span class="sourceLineNo">835</span>        ServerMetrics load = onlineServers.get(name);<a name="line.835"></a>
-<span class="sourceLineNo">836</span>        if (load != null) {<a name="line.836"></a>
-<span class="sourceLineNo">837</span>          if (idleServerPredicator.test(load)) {<a name="line.837"></a>
-<span class="sourceLineNo">838</span>            names.add(name);<a name="line.838"></a>
-<span class="sourceLineNo">839</span>          }<a name="line.839"></a>
-<span class="sourceLineNo">840</span>        }<a name="line.840"></a>
-<span class="sourceLineNo">841</span>      });<a name="line.841"></a>
-<span class="sourceLineNo">842</span>    }<a name="line.842"></a>
-<span class="sourceLineNo">843</span>    return names;<a name="line.843"></a>
-<span class="sourceLineNo">844</span>  }<a name="line.844"></a>
-<span class="sourceLineNo">845</span><a name="line.845"></a>
-<span class="sourceLineNo">846</span>  /** Returns A copy of the internal list of draining servers. */<a name="line.846"></a>
-<span class="sourceLineNo">847</span>  public List&lt;ServerName&gt; getDrainingServersList() {<a name="line.847"></a>
-<span class="sourceLineNo">848</span>    return new ArrayList&lt;&gt;(this.drainingServers);<a name="line.848"></a>
+<span class="sourceLineNo">222</span>    // if use-ip is enabled, we will use ip to expose Master/RS service for client,<a name="line.222"></a>
+<span class="sourceLineNo">223</span>    // see HBASE-27304 for details.<a name="line.223"></a>
+<span class="sourceLineNo">224</span>    boolean useIp = master.getConfiguration().getBoolean(HConstants.HBASE_SERVER_USEIP_ENABLED_KEY,<a name="line.224"></a>
+<span class="sourceLineNo">225</span>      HConstants.HBASE_SERVER_USEIP_ENABLED_DEFAULT);<a name="line.225"></a>
+<span class="sourceLineNo">226</span>    String isaHostName = useIp ? ia.getHostAddress() : ia.getHostName();<a name="line.226"></a>
+<span class="sourceLineNo">227</span>    final String hostname =<a name="line.227"></a>
+<span class="sourceLineNo">228</span>      request.hasUseThisHostnameInstead() ? request.getUseThisHostnameInstead() : isaHostName;<a name="line.228"></a>
+<span class="sourceLineNo">229</span>    ServerName sn = ServerName.valueOf(hostname, request.getPort(), request.getServerStartCode());<a name="line.229"></a>
+<span class="sourceLineNo">230</span>    checkClockSkew(sn, request.getServerCurrentTime());<a name="line.230"></a>
+<span class="sourceLineNo">231</span>    checkIsDead(sn, "STARTUP");<a name="line.231"></a>
+<span class="sourceLineNo">232</span>    if (!checkAndRecordNewServer(sn, ServerMetricsBuilder.of(sn, versionNumber, version))) {<a name="line.232"></a>
+<span class="sourceLineNo">233</span>      LOG.warn(<a name="line.233"></a>
+<span class="sourceLineNo">234</span>        "THIS SHOULD NOT HAPPEN, RegionServerStartup" + " could not record the server: " + sn);<a name="line.234"></a>
+<span class="sourceLineNo">235</span>    }<a name="line.235"></a>
+<span class="sourceLineNo">236</span>    storage.started(sn);<a name="line.236"></a>
+<span class="sourceLineNo">237</span>    return sn;<a name="line.237"></a>
+<span class="sourceLineNo">238</span>  }<a name="line.238"></a>
+<span class="sourceLineNo">239</span><a name="line.239"></a>
+<span class="sourceLineNo">240</span>  /**<a name="line.240"></a>
+<span class="sourceLineNo">241</span>   * Updates last flushed sequence Ids for the regions on server sn<a name="line.241"></a>
+<span class="sourceLineNo">242</span>   */<a name="line.242"></a>
+<span class="sourceLineNo">243</span>  private void updateLastFlushedSequenceIds(ServerName sn, ServerMetrics hsl) {<a name="line.243"></a>
+<span class="sourceLineNo">244</span>    for (Entry&lt;byte[], RegionMetrics&gt; entry : hsl.getRegionMetrics().entrySet()) {<a name="line.244"></a>
+<span class="sourceLineNo">245</span>      byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey()));<a name="line.245"></a>
+<span class="sourceLineNo">246</span>      Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName);<a name="line.246"></a>
+<span class="sourceLineNo">247</span>      long l = entry.getValue().getCompletedSequenceId();<a name="line.247"></a>
+<span class="sourceLineNo">248</span>      // Don't let smaller sequence ids override greater sequence ids.<a name="line.248"></a>
+<span class="sourceLineNo">249</span>      if (LOG.isTraceEnabled()) {<a name="line.249"></a>
+<span class="sourceLineNo">250</span>        LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue<a name="line.250"></a>
+<span class="sourceLineNo">251</span>          + ", completeSequenceId=" + l);<a name="line.251"></a>
+<span class="sourceLineNo">252</span>      }<a name="line.252"></a>
+<span class="sourceLineNo">253</span>      if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue)) {<a name="line.253"></a>
+<span class="sourceLineNo">254</span>        flushedSequenceIdByRegion.put(encodedRegionName, l);<a name="line.254"></a>
+<span class="sourceLineNo">255</span>      } else if (l != HConstants.NO_SEQNUM &amp;&amp; l &lt; existingValue) {<a name="line.255"></a>
+<span class="sourceLineNo">256</span>        LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l<a name="line.256"></a>
+<span class="sourceLineNo">257</span>          + ") that is less than the previous last flushed sequence id (" + existingValue<a name="line.257"></a>
+<span class="sourceLineNo">258</span>          + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring.");<a name="line.258"></a>
+<span class="sourceLineNo">259</span>      }<a name="line.259"></a>
+<span class="sourceLineNo">260</span>      ConcurrentNavigableMap&lt;byte[], Long&gt; storeFlushedSequenceId =<a name="line.260"></a>
+<span class="sourceLineNo">261</span>        computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName,<a name="line.261"></a>
+<span class="sourceLineNo">262</span>          () -&gt; new ConcurrentSkipListMap&lt;&gt;(Bytes.BYTES_COMPARATOR));<a name="line.262"></a>
+<span class="sourceLineNo">263</span>      for (Entry&lt;byte[], Long&gt; storeSeqId : entry.getValue().getStoreSequenceId().entrySet()) {<a name="line.263"></a>
+<span class="sourceLineNo">264</span>        byte[] family = storeSeqId.getKey();<a name="line.264"></a>
+<span class="sourceLineNo">265</span>        existingValue = storeFlushedSequenceId.get(family);<a name="line.265"></a>
+<span class="sourceLineNo">266</span>        l = storeSeqId.getValue();<a name="line.266"></a>
+<span class="sourceLineNo">267</span>        if (LOG.isTraceEnabled()) {<a name="line.267"></a>
+<span class="sourceLineNo">268</span>          LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family)<a name="line.268"></a>
+<span class="sourceLineNo">269</span>            + ", existingValue=" + existingValue + ", completeSequenceId=" + l);<a name="line.269"></a>
+<span class="sourceLineNo">270</span>        }<a name="line.270"></a>
+<span class="sourceLineNo">271</span>        // Don't let smaller sequence ids override greater sequence ids.<a name="line.271"></a>
+<span class="sourceLineNo">272</span>        if (existingValue == null || (l != HConstants.NO_SEQNUM &amp;&amp; l &gt; existingValue.longValue())) {<a name="line.272"></a>
+<span class="sourceLineNo">273</span>          storeFlushedSequenceId.put(family, l);<a name="line.273"></a>
+<span class="sourceLineNo">274</span>        }<a name="line.274"></a>
+<span class="sourceLineNo">275</span>      }<a name="line.275"></a>
+<span class="sourceLineNo">276</span>    }<a name="line.276"></a>
+<span class="sourceLineNo">277</span>  }<a name="line.277"></a>
+<span class="sourceLineNo">278</span><a name="line.278"></a>
+<span class="sourceLineNo">279</span>  public void regionServerReport(ServerName sn, ServerMetrics sl) throws YouAreDeadException {<a name="line.279"></a>
+<span class="sourceLineNo">280</span>    checkIsDead(sn, "REPORT");<a name="line.280"></a>
+<span class="sourceLineNo">281</span>    if (null == this.onlineServers.replace(sn, sl)) {<a name="line.281"></a>
+<span class="sourceLineNo">282</span>      // Already have this host+port combo and its just different start code?<a name="line.282"></a>
+<span class="sourceLineNo">283</span>      // Just let the server in. Presume master joining a running cluster.<a name="line.283"></a>
+<span class="sourceLineNo">284</span>      // recordNewServer is what happens at the end of reportServerStartup.<a name="line.284"></a>
+<span class="sourceLineNo">285</span>      // The only thing we are skipping is passing back to the regionserver<a name="line.285"></a>
+<span class="sourceLineNo">286</span>      // the ServerName to use. Here we presume a master has already done<a name="line.286"></a>
+<span class="sourceLineNo">287</span>      // that so we'll press on with whatever it gave us for ServerName.<a name="line.287"></a>
+<span class="sourceLineNo">288</span>      if (!checkAndRecordNewServer(sn, sl)) {<a name="line.288"></a>
+<span class="sourceLineNo">289</span>        LOG.info("RegionServerReport ignored, could not record the server: " + sn);<a name="line.289"></a>
+<span class="sourceLineNo">290</span>        return; // Not recorded, so no need to move on<a name="line.290"></a>
+<span class="sourceLineNo">291</span>      }<a name="line.291"></a>
+<span class="sourceLineNo">292</span>    }<a name="line.292"></a>
+<span class="sourceLineNo">293</span>    updateLastFlushedSequenceIds(sn, sl);<a name="line.293"></a>
+<span class="sourceLineNo">294</span>  }<a name="line.294"></a>
+<span class="sourceLineNo">295</span><a name="line.295"></a>
+<span class="sourceLineNo">296</span>  /**<a name="line.296"></a>
+<span class="sourceLineNo">297</span>   * Check is a server of same host and port already exists, if not, or the existed one got a<a name="line.297"></a>
+<span class="sourceLineNo">298</span>   * smaller start code, record it.<a name="line.298"></a>
+<span class="sourceLineNo">299</span>   * @param serverName the server to check and record<a name="line.299"></a>
+<span class="sourceLineNo">300</span>   * @param sl         the server load on the server<a name="line.300"></a>
+<span class="sourceLineNo">301</span>   * @return true if the server is recorded, otherwise, false<a name="line.301"></a>
+<span class="sourceLineNo">302</span>   */<a name="line.302"></a>
+<span class="sourceLineNo">303</span>  boolean checkAndRecordNewServer(final ServerName serverName, final ServerMetrics sl) {<a name="line.303"></a>
+<span class="sourceLineNo">304</span>    ServerName existingServer = null;<a name="line.304"></a>
+<span class="sourceLineNo">305</span>    synchronized (this.onlineServers) {<a name="line.305"></a>
+<span class="sourceLineNo">306</span>      existingServer = findServerWithSameHostnamePortWithLock(serverName);<a name="line.306"></a>
+<span class="sourceLineNo">307</span>      if (existingServer != null &amp;&amp; (existingServer.getStartcode() &gt; serverName.getStartcode())) {<a name="line.307"></a>
+<span class="sourceLineNo">308</span>        LOG.info("Server serverName=" + serverName + " rejected; we already have "<a name="line.308"></a>
+<span class="sourceLineNo">309</span>          + existingServer.toString() + " registered with same hostname and port");<a name="line.309"></a>
+<span class="sourceLineNo">310</span>        return false;<a name="line.310"></a>
+<span class="sourceLineNo">311</span>      }<a name="line.311"></a>
+<span class="sourceLineNo">312</span>      recordNewServerWithLock(serverName, sl);<a name="line.312"></a>
+<span class="sourceLineNo">313</span>    }<a name="line.313"></a>
+<span class="sourceLineNo">314</span><a name="line.314"></a>
+<span class="sourceLineNo">315</span>    // Tell our listeners that a server was added<a name="line.315"></a>
+<span class="sourceLineNo">316</span>    if (!this.listeners.isEmpty()) {<a name="line.316"></a>
+<span class="sourceLineNo">317</span>      for (ServerListener listener : this.listeners) {<a name="line.317"></a>
+<span class="sourceLineNo">318</span>        listener.serverAdded(serverName);<a name="line.318"></a>
+<span class="sourceLineNo">319</span>      }<a name="line.319"></a>
+<span class="sourceLineNo">320</span>    }<a name="line.320"></a>
+<span class="sourceLineNo">321</span><a name="line.321"></a>
+<span class="sourceLineNo">322</span>    // Note that we assume that same ts means same server, and don't expire in that case.<a name="line.322"></a>
+<span class="sourceLineNo">323</span>    // TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.<a name="line.323"></a>
+<span class="sourceLineNo">324</span>    if (existingServer != null &amp;&amp; (existingServer.getStartcode() &lt; serverName.getStartcode())) {<a name="line.324"></a>
+<span class="sourceLineNo">325</span>      LOG.info("Triggering server recovery; existingServer " + existingServer<a name="line.325"></a>
+<span class="sourceLineNo">326</span>        + " looks stale, new server:" + serverName);<a name="line.326"></a>
+<span class="sourceLineNo">327</span>      expireServer(existingServer);<a name="line.327"></a>
+<span class="sourceLineNo">328</span>    }<a name="line.328"></a>
+<span class="sourceLineNo">329</span>    return true;<a name="line.329"></a>
+<span class="sourceLineNo">330</span>  }<a name="line.330"></a>
+<span class="sourceLineNo">331</span><a name="line.331"></a>
+<span class="sourceLineNo">332</span>  /**<a name="line.332"></a>
+<span class="sourceLineNo">333</span>   * Find out the region servers crashed between the crash of the previous master instance and the<a name="line.333"></a>
+<span class="sourceLineNo">334</span>   * current master instance and schedule SCP for them.<a name="line.334"></a>
+<span class="sourceLineNo">335</span>   * &lt;p/&gt;<a name="line.335"></a>
+<span class="sourceLineNo">336</span>   * Since the {@code RegionServerTracker} has already helped us to construct the online servers set<a name="line.336"></a>
+<span class="sourceLineNo">337</span>   * by scanning zookeeper, now we can compare the online servers with {@code liveServersFromWALDir}<a name="line.337"></a>
+<span class="sourceLineNo">338</span>   * to find out whether there are servers which are already dead.<a name="line.338"></a>
+<span class="sourceLineNo">339</span>   * &lt;p/&gt;<a name="line.339"></a>
+<span class="sourceLineNo">340</span>   * Must be called inside the initialization method of {@code RegionServerTracker} to avoid<a name="line.340"></a>
+<span class="sourceLineNo">341</span>   * concurrency issue.<a name="line.341"></a>
+<span class="sourceLineNo">342</span>   * @param deadServersFromPE     the region servers which already have a SCP associated.<a name="line.342"></a>
+<span class="sourceLineNo">343</span>   * @param liveServersFromWALDir the live region servers from wal directory.<a name="line.343"></a>
+<span class="sourceLineNo">344</span>   */<a name="line.344"></a>
+<span class="sourceLineNo">345</span>  void findDeadServersAndProcess(Set&lt;ServerName&gt; deadServersFromPE,<a name="line.345"></a>
+<span class="sourceLineNo">346</span>    Set&lt;ServerName&gt; liveServersFromWALDir) {<a name="line.346"></a>
+<span class="sourceLineNo">347</span>    deadServersFromPE.forEach(deadservers::putIfAbsent);<a name="line.347"></a>
+<span class="sourceLineNo">348</span>    liveServersFromWALDir.stream().filter(sn -&gt; !onlineServers.containsKey(sn))<a name="line.348"></a>
+<span class="sourceLineNo">349</span>      .forEach(this::expireServer);<a name="line.349"></a>
+<span class="sourceLineNo">350</span>  }<a name="line.350"></a>
+<span class="sourceLineNo">351</span><a name="line.351"></a>
+<span class="sourceLineNo">352</span>  /**<a name="line.352"></a>
+<span class="sourceLineNo">353</span>   * Checks if the clock skew between the server and the master. If the clock skew exceeds the<a name="line.353"></a>
+<span class="sourceLineNo">354</span>   * configured max, it will throw an exception; if it exceeds the configured warning threshold, it<a name="line.354"></a>
+<span class="sourceLineNo">355</span>   * will log a warning but start normally.<a name="line.355"></a>
+<span class="sourceLineNo">356</span>   * @param serverName Incoming servers's name n * @throws ClockOutOfSyncException if the skew<a name="line.356"></a>
+<span class="sourceLineNo">357</span>   *                   exceeds the configured max value<a name="line.357"></a>
+<span class="sourceLineNo">358</span>   */<a name="line.358"></a>
+<span class="sourceLineNo">359</span>  private void checkClockSkew(final ServerName serverName, final long serverCurrentTime)<a name="line.359"></a>
+<span class="sourceLineNo">360</span>    throws ClockOutOfSyncException {<a name="line.360"></a>
+<span class="sourceLineNo">361</span>    long skew = Math.abs(EnvironmentEdgeManager.currentTime() - serverCurrentTime);<a name="line.361"></a>
+<span class="sourceLineNo">362</span>    if (skew &gt; maxSkew) {<a name="line.362"></a>
+<span class="sourceLineNo">363</span>      String message = "Server " + serverName + " has been "<a name="line.363"></a>
+<span class="sourceLineNo">364</span>        + "rejected; Reported time is too far out of sync with master.  " + "Time difference of "<a name="line.364"></a>
+<span class="sourceLineNo">365</span>        + skew + "ms &gt; max allowed of " + maxSkew + "ms";<a name="line.365"></a>
+<span class="sourceLineNo">366</span>      LOG.warn(message);<a name="line.366"></a>
+<span class="sourceLineNo">367</span>      throw new ClockOutOfSyncException(message);<a name="line.367"></a>
+<span class="sourceLineNo">368</span>    } else if (skew &gt; warningSkew) {<a name="line.368"></a>
+<span class="sourceLineNo">369</span>      String message = "Reported time for server " + serverName + " is out of sync with master "<a name="line.369"></a>
+<span class="sourceLineNo">370</span>        + "by " + skew + "ms. (Warning threshold is " + warningSkew + "ms; " + "error threshold is "<a name="line.370"></a>
+<span class="sourceLineNo">371</span>        + maxSkew + "ms)";<a name="line.371"></a>
... 9283 lines suppressed ...