This patch modifies TcpPing and its callers to make the source address
selection optional. Usually, the kernel will know better what
source address to use, just in some cases we want to enforce a given
source address so it makes sense to make this optional.
Reviewed-by: ultrotter
"""Starts the master.
"""
"""Starts the master.
"""
- if utils.TcpPing(utils.HostInfo().name, master_ip,
- constants.DEFAULT_NODED_PORT):
- if utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, master_ip,
- constants.DEFAULT_NODED_PORT):
+ if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
+ if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT,
+ source=constants.LOCALHOST_IP_ADDRESS):
# we already have the ip:
if debug:
sys.stderr.write("Notice: already started.\n")
# we already have the ip:
if debug:
sys.stderr.write("Notice: already started.\n")
"""Do a TcpPing on the remote node.
"""
"""Do a TcpPing on the remote node.
"""
- return utils.TcpPing(params[0], params[1], params[2],
- timeout=params[3], live_port_needed=params[4])
+ return utils.TcpPing(params[1], params[2], timeout=params[3],
+ live_port_needed=params[4], source=params[0])
@staticmethod
def perspective_node_info(params):
@staticmethod
def perspective_node_info(params):
self.clustername = clustername = utils.HostInfo(self.op.cluster_name)
self.clustername = clustername = utils.HostInfo(self.op.cluster_name)
- if not utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, hostname.ip,
- constants.DEFAULT_NODED_PORT):
+ if not utils.TcpPing(hostname.ip, constants.DEFAULT_NODED_PORT,
+ source=constants.LOCALHOST_IP_ADDRESS):
raise errors.OpPrereqError("Inconsistency: this host's name resolves"
" to %s,\nbut this ip address does not"
" belong to this host."
raise errors.OpPrereqError("Inconsistency: this host's name resolves"
" to %s,\nbut this ip address does not"
" belong to this host."
raise errors.OpPrereqError("Invalid secondary ip given")
if (secondary_ip and
secondary_ip != hostname.ip and
raise errors.OpPrereqError("Invalid secondary ip given")
if (secondary_ip and
secondary_ip != hostname.ip and
- (not utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, secondary_ip,
- constants.DEFAULT_NODED_PORT))):
+ (not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
+ source=constants.LOCALHOST_IP_ADDRESS))):
raise errors.OpPrereqError("You gave %s as secondary IP,"
" but it does not belong to this host." %
secondary_ip)
raise errors.OpPrereqError("You gave %s as secondary IP,"
" but it does not belong to this host." %
secondary_ip)
" new node doesn't have one")
# checks reachablity
" new node doesn't have one")
# checks reachablity
- if not utils.TcpPing(utils.HostInfo().name,
- primary_ip,
- constants.DEFAULT_NODED_PORT):
+ if not utils.TcpPing(primary_ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("Node not reachable by ping")
if not newbie_singlehomed:
# check reachability from my secondary ip to newbie's secondary ip
raise errors.OpPrereqError("Node not reachable by ping")
if not newbie_singlehomed:
# check reachability from my secondary ip to newbie's secondary ip
- if not utils.TcpPing(myself.secondary_ip,
- secondary_ip,
- constants.DEFAULT_NODED_PORT):
+ if not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
+ source=myself.secondary_ip):
raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
" based ping to noded port")
raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
" based ping to noded port")
" adding an instance in start mode")
if self.op.ip_check:
" adding an instance in start mode")
if self.op.ip_check:
- if utils.TcpPing(utils.HostInfo().name, hostname1.ip,
- constants.DEFAULT_NODED_PORT):
+ if utils.TcpPing(hostname1.ip, constants.DEFAULT_NODED_PORT):
raise errors.OpPrereqError("IP %s of instance %s already in use" %
(hostname1.ip, instance_name))
raise errors.OpPrereqError("IP %s of instance %s already in use" %
(hostname1.ip, instance_name))
return ' '.join([ShellQuote(i) for i in args])
return ' '.join([ShellQuote(i) for i in args])
-
-def TcpPing(source, target, port, timeout=10, live_port_needed=False):
+def TcpPing(target, port, timeout=10, live_port_needed=False, source=None):
"""Simple ping implementation using TCP connect(2).
"""Simple ping implementation using TCP connect(2).
- Try to do a TCP connect(2) from the specified source IP to the specified
- target IP and the specified target port. If live_port_needed is set to true,
- requires the remote end to accept the connection. The timeout is specified
- in seconds and defaults to 10 seconds
+ Try to do a TCP connect(2) from an optional source IP to the
+ specified target IP and the specified target port. If the optional
+ parameter live_port_needed is set to true, requires the remote end
+ to accept the connection. The timeout is specified in seconds and
+ defaults to 10 seconds. If the source optional argument is not
+ passed, the source address selection is left to the kernel,
+ otherwise we try to connect using the passed address (failures to
+ bind other than EADDRNOTAVAIL will be ignored).
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sucess = False
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sucess = False
- try:
- sock.bind((source, 0))
- except socket.error, (errcode, errstring):
- if errcode == errno.EADDRNOTAVAIL:
- success = False
+ if source is not None:
+ try:
+ sock.bind((source, 0))
+ except socket.error, (errcode, errstring):
+ if errcode == errno.EADDRNOTAVAIL:
+ success = False
def testTcpPingToLocalHostAccept(self):
self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
def testTcpPingToLocalHostAccept(self):
self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
- constants.LOCALHOST_IP_ADDRESS,
self.listenerport,
timeout=10,
self.listenerport,
timeout=10,
- live_port_needed=True),
+ live_port_needed=True,
+ source=constants.LOCALHOST_IP_ADDRESS,
+ ),
"failed to connect to test listener")
"failed to connect to test listener")
+ self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
+ self.listenerport,
+ timeout=10,
+ live_port_needed=True,
+ ),
+ "failed to connect to test listener (no source)")
+
class TestTcpPingDeaf(unittest.TestCase):
"""Testcase for TCP version of ping - against non listen(2)ing port"""
class TestTcpPingDeaf(unittest.TestCase):
"""Testcase for TCP version of ping - against non listen(2)ing port"""
def testTcpPingToLocalHostAcceptDeaf(self):
self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
def testTcpPingToLocalHostAcceptDeaf(self):
self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
- constants.LOCALHOST_IP_ADDRESS,
self.deaflistenerport,
timeout=constants.TCP_PING_TIMEOUT,
self.deaflistenerport,
timeout=constants.TCP_PING_TIMEOUT,
- live_port_needed=True), # need successful connect(2)
+ live_port_needed=True,
+ source=constants.LOCALHOST_IP_ADDRESS,
+ ), # need successful connect(2)
"successfully connected to deaf listener")
"successfully connected to deaf listener")
+ self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
+ self.deaflistenerport,
+ timeout=constants.TCP_PING_TIMEOUT,
+ live_port_needed=True,
+ ), # need successful connect(2)
+ "successfully connected to deaf listener (no source addr)")
+
def testTcpPingToLocalHostNoAccept(self):
self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
def testTcpPingToLocalHostNoAccept(self):
self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
- constants.LOCALHOST_IP_ADDRESS,
self.deaflistenerport,
timeout=constants.TCP_PING_TIMEOUT,
self.deaflistenerport,
timeout=constants.TCP_PING_TIMEOUT,
- live_port_needed=False), # ECONNREFUSED is OK
+ live_port_needed=False,
+ source=constants.LOCALHOST_IP_ADDRESS,
+ ), # ECONNREFUSED is OK
"failed to ping alive host on deaf port")
"failed to ping alive host on deaf port")
+ self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
+ self.deaflistenerport,
+ timeout=constants.TCP_PING_TIMEOUT,
+ live_port_needed=False,
+ ), # ECONNREFUSED is OK
+ "failed to ping alive host on deaf port (no source addr)")
+
class TestListVisibleFiles(unittest.TestCase):
"""Test case for ListVisibleFiles"""
class TestListVisibleFiles(unittest.TestCase):
"""Test case for ListVisibleFiles"""