X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=xenserver%2Fopt_xensource_libexec_interface-reconfigure;h=6de62b38740188e70d911a50bc075fcb1772ad82;hb=449776d81d7b03d9b5f552b402c8a619323e8aa2;hp=29d79added53d0f4cc1c1fb2e72d14d72523e4f3;hpb=0bb1f43dd8f5e894ed45d158daa5f94f4990c05a;p=openvswitch diff --git a/xenserver/opt_xensource_libexec_interface-reconfigure b/xenserver/opt_xensource_libexec_interface-reconfigure index 29d79add..6de62b38 100755 --- a/xenserver/opt_xensource_libexec_interface-reconfigure +++ b/xenserver/opt_xensource_libexec_interface-reconfigure @@ -543,31 +543,36 @@ def run_command(command): return False return True +def read_first_line_of_file(name): + file = None + try: + file = open(name, 'r') + return file.readline().rstrip('\n') + finally: + if file != None: + file.close() + def down_netdev(interface, deconfigure=True): if not interface_exists(interface): log("down_netdev: interface %s does not exist, ignoring" % interface) return - argv = ["/sbin/ifconfig", interface, 'down'] if deconfigure: - argv += ['0.0.0.0'] - # Kill dhclient. pidfile_name = '/var/run/dhclient-%s.pid' % interface - pidfile = None try: - pidfile = open(pidfile_name, 'r') - os.kill(int(pidfile.readline()), signal.SIGTERM) + os.kill(int(read_first_line_of_file(pidfile_name)), signal.SIGTERM) except: pass - if pidfile != None: - pidfile.close() # Remove dhclient pidfile. try: os.remove(pidfile_name) except: pass - run_command(argv) + + run_command(["/sbin/ifconfig", interface, '0.0.0.0']) + + run_command(["/sbin/ifconfig", interface, 'down']) def up_netdev(interface): run_command(["/sbin/ifconfig", interface, 'up']) @@ -750,6 +755,9 @@ def configure_bond(pif): argv += ["--add=bonding.%s.slave=%s" % (interface, slave) for slave in physdevs] + if pifrec['MAC'] != "": + argv += ['--add=port.%s.mac=%s' % (interface, pifrec['MAC'])] + # Bonding options. bond_options = { "mode": "balance-slb", @@ -786,6 +794,10 @@ def action_up(pif): bond_master = pif else: bond_master = None + if bond_master: + bond_slaves = get_bond_slaves_of_pif(bond_master) + else: + bond_slaves = [] bond_masters = get_bond_masters_of_pif(pif) # Support "rpm -e vswitch" gracefully by keeping Centos configuration @@ -831,6 +843,15 @@ def action_up(pif): for physdev in physdevs: down_netdev(physdev) + # If we are bringing up a bond, remove IP addresses from the + # slaves (because we are implicitly being asked to take them down). + # + # Conversely, if we are bringing up an interface that has bond + # masters, remove IP addresses from the bond master (because we + # are implicitly being asked to take it down). + for bond_pif in bond_slaves + bond_masters: + run_command(["/sbin/ifconfig", ipdev_name(bond_pif), '0.0.0.0']) + # Remove all keys related to pif and any bond masters linked to PIF. del_ports = [ipdev] + physdevs + bond_masters if vlan_slave and bond_master: @@ -872,6 +893,16 @@ def action_up(pif): net = db.get_pif_record(nwpif)['network'] network_uuids += [db.get_network_record(net)['uuid']] + # Bring up bond slaves early, because ovs-vswitchd initially + # enables or disables bond slaves based on whether carrier is + # detected when they are added, and a network device that is down + # always reports "no carrier". + bond_slave_physdevs = [] + for slave in bond_slaves: + bond_slave_physdevs += physdev_names(slave) + for slave_physdev in bond_slave_physdevs: + up_netdev(slave_physdev) + # Now modify the ovs-vswitchd config file. argv = [] for port in set(del_ports): @@ -906,14 +937,28 @@ def action_up(pif): # Configure network devices. configure_netdev(pif) - # Bring up VLAN slave and bond slaves. + # Bring up VLAN slave, plus physical devices other than bond + # slaves (which we brought up earlier). if vlan_slave: up_netdev(ipdev_name(vlan_slave)) - for physdev in physdevs: + for physdev in set(physdevs) - set(bond_slave_physdevs): up_netdev(physdev) # Update /etc/issue (which contains the IP address of the management interface) os.system("/sbin/update-issue") + + if bond_slaves: + # There seems to be a race somewhere: without this sleep, using + # XenCenter to create a bond that becomes the management interface + # fails with "The underlying connection was closed: A connection that + # was expected to be kept alive was closed by the server." on every + # second or third try, even though /var/log/messages doesn't show + # anything unusual. + # + # The race is probably present even without vswitch, but bringing up a + # bond without vswitch involves a built-in pause of 10 seconds or more + # to wait for the bond to transition from learning to forwarding state. + time.sleep(5) def action_down(pif): rec = db.get_pif_record(pif)