From 6dea02b2605d398e0ab499b9813c4718a9608912 Mon Sep 17 00:00:00 2001 From: Rajeshbabu Chintaguntla Date: Tue, 14 Oct 2014 02:24:21 +0000 Subject: [PATCH] HBASE-10200 Better error message when HttpServer fails to start due to java.net.BindException(Kiran Kumar M R) --- .../apache/hadoop/hbase/util/Addressing.java | 21 +++++++++++++++++++ .../apache/hadoop/hbase/master/HMaster.java | 12 ++++++++++- .../hbase/regionserver/HRegionServer.java | 10 +++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Addressing.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Addressing.java index 8fb554f2831..a7c929feac5 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Addressing.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Addressing.java @@ -102,4 +102,25 @@ public class Addressing { throw new SocketException("Can't get our ip address, interfaces are: " + interfaces); } + + /** + * Given an InetAddress, checks to see if the address is a local address, by comparing the address + * with all the interfaces on the node. + * @param addr address to check if it is local node's address + * @return true if the address corresponds to the local node + */ + public static boolean isLocalAddress(InetAddress addr) { + // Check if the address is any local or loop back + boolean local = addr.isAnyLocalAddress() || addr.isLoopbackAddress(); + + // Check if the address is defined on any interface + if (!local) { + try { + local = NetworkInterface.getByInetAddress(addr) != null; + } catch (SocketException e) { + local = false; + } + } + return local; + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index 61d1b7aaf65..831c4dacc27 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -109,6 +109,7 @@ import org.apache.hadoop.hbase.regionserver.RSRpcServices; import org.apache.hadoop.hbase.regionserver.RegionSplitPolicy; import org.apache.hadoop.hbase.replication.regionserver.Replication; import org.apache.hadoop.hbase.security.UserProvider; +import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CompressionTest; import org.apache.hadoop.hbase.util.FSUtils; @@ -321,11 +322,20 @@ public class HMaster extends HRegionServer implements MasterServices, Server { if (infoPort < 0 || infoServer == null) { return; } + String addr = conf.get("hbase.master.info.bindAddress", "0.0.0.0"); + if (!Addressing.isLocalAddress(InetAddress.getByName(addr))) { + String msg = + "Failed to start redirecting jetty server. Address " + addr + + " does not belong to this host. Correct configuration parameter: " + + "hbase.master.info.bindAddress"; + LOG.error(msg); + throw new IOException(msg); + } RedirectServlet.regionServerInfoPort = infoServer.getPort(); masterJettyServer = new org.mortbay.jetty.Server(); Connector connector = new SelectChannelConnector(); - connector.setHost(conf.get("hbase.master.info.bindAddress", "0.0.0.0")); + connector.setHost(addr); connector.setPort(infoPort); masterJettyServer.addConnector(connector); masterJettyServer.setStopAtShutdown(true); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java index 21de0281829..008e443af54 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java @@ -45,6 +45,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.net.InetAddress; import javax.management.ObjectName; import javax.servlet.http.HttpServlet; @@ -127,6 +128,7 @@ import org.apache.hadoop.hbase.regionserver.wal.HLogUtil; import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener; import org.apache.hadoop.hbase.security.UserProvider; import org.apache.hadoop.hbase.trace.SpanReceiverHost; +import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.ByteStringer; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CompressionTest; @@ -1662,6 +1664,14 @@ public class HRegionServer extends HasThread implements // -1 is for disabling info server if (port < 0) return port; String addr = this.conf.get("hbase.regionserver.info.bindAddress", "0.0.0.0"); + if (!Addressing.isLocalAddress(InetAddress.getByName(addr))) { + String msg = + "Failed to start http info server. Address " + addr + + " does not belong to this host. Correct configuration parameter: " + + "hbase.regionserver.info.bindAddress"; + LOG.error(msg); + throw new IOException(msg); + } // check if auto port bind enabled boolean auto = this.conf.getBoolean(HConstants.REGIONSERVER_INFO_PORT_AUTO, false);