Revision b15d625f

b/daemons/ganeti-master
106 106
  """Starts the master.
107 107

  
108 108
  """
109
  if utils.TcpPing(utils.HostInfo().name, master_ip,
110
                   constants.DEFAULT_NODED_PORT):
111
    if utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, master_ip,
112
                     constants.DEFAULT_NODED_PORT):
109
  if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT):
110
    if utils.TcpPing(master_ip, constants.DEFAULT_NODED_PORT,
111
                     source=constants.LOCALHOST_IP_ADDRESS):
113 112
      # we already have the ip:
114 113
      if debug:
115 114
        sys.stderr.write("Notice: already started.\n")
b/daemons/ganeti-noded
378 378
    """Do a TcpPing on the remote node.
379 379

  
380 380
    """
381
    return utils.TcpPing(params[0], params[1], params[2],
382
                         timeout=params[3], live_port_needed=params[4])
381
    return utils.TcpPing(params[1], params[2], timeout=params[3],
382
                         live_port_needed=params[4], source=params[0])
383 383

  
384 384
  @staticmethod
385 385
  def perspective_node_info(params):
b/lib/cmdlib.py
516 516

  
517 517
    self.clustername = clustername = utils.HostInfo(self.op.cluster_name)
518 518

  
519
    if not utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, hostname.ip,
520
                         constants.DEFAULT_NODED_PORT):
519
    if not utils.TcpPing(hostname.ip, constants.DEFAULT_NODED_PORT,
520
                         source=constants.LOCALHOST_IP_ADDRESS):
521 521
      raise errors.OpPrereqError("Inconsistency: this host's name resolves"
522 522
                                 " to %s,\nbut this ip address does not"
523 523
                                 " belong to this host."
......
528 528
      raise errors.OpPrereqError("Invalid secondary ip given")
529 529
    if (secondary_ip and
530 530
        secondary_ip != hostname.ip and
531
        (not utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, secondary_ip,
532
                           constants.DEFAULT_NODED_PORT))):
531
        (not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
532
                           source=constants.LOCALHOST_IP_ADDRESS))):
533 533
      raise errors.OpPrereqError("You gave %s as secondary IP,"
534 534
                                 " but it does not belong to this host." %
535 535
                                 secondary_ip)
......
1478 1478
                                   " new node doesn't have one")
1479 1479

  
1480 1480
    # checks reachablity
1481
    if not utils.TcpPing(utils.HostInfo().name,
1482
                         primary_ip,
1483
                         constants.DEFAULT_NODED_PORT):
1481
    if not utils.TcpPing(primary_ip, constants.DEFAULT_NODED_PORT):
1484 1482
      raise errors.OpPrereqError("Node not reachable by ping")
1485 1483

  
1486 1484
    if not newbie_singlehomed:
1487 1485
      # check reachability from my secondary ip to newbie's secondary ip
1488
      if not utils.TcpPing(myself.secondary_ip,
1489
                           secondary_ip,
1490
                           constants.DEFAULT_NODED_PORT):
1486
      if not utils.TcpPing(secondary_ip, constants.DEFAULT_NODED_PORT,
1487
                           source=myself.secondary_ip):
1491 1488
        raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
1492 1489
                                   " based ping to noded port")
1493 1490

  
......
3076 3073
                                 " adding an instance in start mode")
3077 3074

  
3078 3075
    if self.op.ip_check:
3079
      if utils.TcpPing(utils.HostInfo().name, hostname1.ip,
3080
                       constants.DEFAULT_NODED_PORT):
3076
      if utils.TcpPing(hostname1.ip, constants.DEFAULT_NODED_PORT):
3081 3077
        raise errors.OpPrereqError("IP %s of instance %s already in use" %
3082 3078
                                   (hostname1.ip, instance_name))
3083 3079

  
b/lib/utils.py
909 909
  return ' '.join([ShellQuote(i) for i in args])
910 910

  
911 911

  
912

  
913
def TcpPing(source, target, port, timeout=10, live_port_needed=False):
912
def TcpPing(target, port, timeout=10, live_port_needed=False, source=None):
914 913
  """Simple ping implementation using TCP connect(2).
915 914

  
916
  Try to do a TCP connect(2) from the specified source IP to the specified
917
  target IP and the specified target port. If live_port_needed is set to true,
918
  requires the remote end to accept the connection. The timeout is specified
919
  in seconds and defaults to 10 seconds
915
  Try to do a TCP connect(2) from an optional source IP to the
916
  specified target IP and the specified target port. If the optional
917
  parameter live_port_needed is set to true, requires the remote end
918
  to accept the connection. The timeout is specified in seconds and
919
  defaults to 10 seconds. If the source optional argument is not
920
  passed, the source address selection is left to the kernel,
921
  otherwise we try to connect using the passed address (failures to
922
  bind other than EADDRNOTAVAIL will be ignored).
920 923

  
921 924
  """
922 925
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
923 926

  
924 927
  sucess = False
925 928

  
926
  try:
927
    sock.bind((source, 0))
928
  except socket.error, (errcode, errstring):
929
    if errcode == errno.EADDRNOTAVAIL:
930
      success = False
929
  if source is not None:
930
    try:
931
      sock.bind((source, 0))
932
    except socket.error, (errcode, errstring):
933
      if errcode == errno.EADDRNOTAVAIL:
934
        success = False
931 935

  
932 936
  sock.settimeout(timeout)
933 937

  
b/test/ganeti.utils_unittest.py
533 533

  
534 534
  def testTcpPingToLocalHostAccept(self):
535 535
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
536
                         constants.LOCALHOST_IP_ADDRESS,
537 536
                         self.listenerport,
538 537
                         timeout=10,
539
                         live_port_needed=True),
538
                         live_port_needed=True,
539
                         source=constants.LOCALHOST_IP_ADDRESS,
540
                         ),
540 541
                 "failed to connect to test listener")
541 542

  
543
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
544
                         self.listenerport,
545
                         timeout=10,
546
                         live_port_needed=True,
547
                         ),
548
                 "failed to connect to test listener (no source)")
549

  
542 550

  
543 551
class TestTcpPingDeaf(unittest.TestCase):
544 552
  """Testcase for TCP version of ping - against non listen(2)ing port"""
......
554 562

  
555 563
  def testTcpPingToLocalHostAcceptDeaf(self):
556 564
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
557
                        constants.LOCALHOST_IP_ADDRESS,
558 565
                        self.deaflistenerport,
559 566
                        timeout=constants.TCP_PING_TIMEOUT,
560
                        live_port_needed=True), # need successful connect(2)
567
                        live_port_needed=True,
568
                        source=constants.LOCALHOST_IP_ADDRESS,
569
                        ), # need successful connect(2)
561 570
                "successfully connected to deaf listener")
562 571

  
572
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
573
                        self.deaflistenerport,
574
                        timeout=constants.TCP_PING_TIMEOUT,
575
                        live_port_needed=True,
576
                        ), # need successful connect(2)
577
                "successfully connected to deaf listener (no source addr)")
578

  
563 579
  def testTcpPingToLocalHostNoAccept(self):
564 580
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
565
                         constants.LOCALHOST_IP_ADDRESS,
566 581
                         self.deaflistenerport,
567 582
                         timeout=constants.TCP_PING_TIMEOUT,
568
                         live_port_needed=False), # ECONNREFUSED is OK
583
                         live_port_needed=False,
584
                         source=constants.LOCALHOST_IP_ADDRESS,
585
                         ), # ECONNREFUSED is OK
569 586
                 "failed to ping alive host on deaf port")
570 587

  
588
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
589
                         self.deaflistenerport,
590
                         timeout=constants.TCP_PING_TIMEOUT,
591
                         live_port_needed=False,
592
                         ), # ECONNREFUSED is OK
593
                 "failed to ping alive host on deaf port (no source addr)")
594

  
571 595

  
572 596
class TestListVisibleFiles(unittest.TestCase):
573 597
  """Test case for ListVisibleFiles"""

Also available in: Unified diff