def scanConfiguration(): """ Returns a dictionary of string -> NIC with a snapshot of the NIC configuration. Filter out any NICs that have been reserved by the iBFT for use with boot time iSCSI targets. (iBFT = iSCSI Boot Firmware Tables.) This is because we cannot use NICs that are used to access iSCSI LUNs for other purposes e.g. XenServer Management. """ conf = {} nics = [] bdn = BiosDevName() bdn.run() for nif in getNetifList(): if nif not in diskutil.ibft_reserved_nics: nics.append(nif) for nic in bdn.devices: name = nic.get("Kernel name", "") if name in nics: conf[name] = NIC(nic) return conf
def remap_netdevs(remap_list): # rename everything sideways to safe faffing with temp renanes for x in ( x for x in os.listdir("/sys/class/net/") if x[:3] == "eth" ): util.runCmd2(['ip', 'link', 'set', x, 'name', 'side-'+x]) bdn = BiosDevName() bdn.run(policy="physical") all_devices = bdn.devices[:] parsed_list = filter(lambda x: x is not None, map(parse_arg, remap_list)) # python sorting is stable so the following results in sorted by # static/dynamic, then subsorted by ethname parsed_list.sort(key=lambda x: x[0]) parsed_list.sort(key=lambda x: x[1]) for rule in parsed_list: target, sd, method, val = rule # If the rule specifies an SMBios Label if method == METH_LABEL: dev = None for d in bdn.devices: if 'SMBIOS Label' in d and d['SMBIOS Label'] == val: dev = d break if dev is None: xelogging.log("No SMBios Label found for %s rule - Discarding" % target) continue else: bdn.devices.remove(dev) if sd == DEV_STATIC: srules.append('%s: label="%s"' % (target, val)) else: drules.append([dev['Assigned MAC'].lower(), dev['Bus Info'].lower(), target]) xelogging.log("Renaming '%s' to '%s' due to SMBIOS Label" % ( dev['Kernel name'], target )) util.runCmd2(['ip', 'link', 'set', dev['Kernel name'], 'name', target]) elif method == METH_MAC: dev = None for d in bdn.devices: if d['Assigned MAC'].lower() == val: dev = d break if dev is None: xelogging.log("No device with mac address '%s' found for %s " "rule - Discarding" % (val, target)) continue else: bdn.devices.remove(dev) if sd == DEV_STATIC: srules.append('%s: mac="%s"' % (target, val)) else: drules.append([val, dev['Bus Info'].lower(), target]) xelogging.log("Renaming '%s' to '%s' due to MAC address" % ( dev['Kernel name'], target )) util.runCmd2(['ip', 'link', 'set', dev['Kernel name'], 'name', target]) elif method == METH_PCI: dev = None for d in bdn.devices: if d['Bus Info'].lower() == val: dev = d break if dev is None: xelogging.log("No device with pci address '%s' found for %s " "rule - Discarding" % (val, target)) continue else: bdn.devices.remove(dev) if sd == DEV_STATIC: srules.append('%s: pci="%s"' % (target, val)) else: drules.append([dev['Assigned MAC'].lower(), val, target]) xelogging.log("Renaming '%s' to '%s' due to PCI mapping" % ( dev['Kernel name'], target )) util.runCmd2(['ip', 'link', 'set', dev['Kernel name'], 'name', target]) elif method == METH_PPN: dev = None for d in bdn.devices: if d['BIOS device'] == val: dev = d break if dev is None: xelogging.log("No device with physical address '%s' found for " "%s rule - Discarding" % (val, target)) continue else: bdn.devices.remove(dev) if sd == DEV_STATIC: srules.append('%s: ppn="%s"' % (target, val)) else: drules.append([dev['Assigned MAC'].lower(), dev['Bus Info'].lower(), target]) xelogging.log("Renaming '%s' to '%s' due to Physical name" % ( dev['Kernel name'], target )) util.runCmd2(['ip', 'link', 'set', dev['Kernel name'], 'name', target]) else: xelogging.log("Unrecognised method - Ignoring") side_devs = [ x for x in os.listdir("/sys/class/net") if x[:5] == "side-" ] side_devs.sort(key=lambda x: int(x[8:])) if len(side_devs): xelogging.log("Renaming devices which have not been displaced by mapping rules") for x in side_devs: if not os.path.exists("/sys/class/net/"+x[5:]): for dev in all_devices: if dev['Kernel name'] == x: drules.append([dev['Assigned MAC'].lower(), dev['Bus Info'].lower(), x[5:]]) util.runCmd2(['ip', 'link', 'set', x, 'name', x[5:]]) def gen_free_netdev(): x = -1 while True: x += 1 if not os.path.exists("/sys/class/net/eth%d" % x): yield "eth%d" % x free_netdev = gen_free_netdev() side_devs = [ x for x in os.listdir("/sys/class/net") if x[:5] == "side-" ] side_devs.sort(key=lambda x: int(x[8:])) if len(side_devs): xelogging.log("Reallocating names for devices which have been displaced") for x in side_devs: free_dev = free_netdev.next() for dev in all_devices: if dev['Kernel name'] == x: drules.append([dev['Assigned MAC'].lower(), dev['Bus Info'].lower(), free_dev]) util.runCmd2(['ip', 'link', 'set', x, 'name', free_dev]) xelogging.log("All done ordering the network devices") xelogging.log("Static rules = %r" % srules) xelogging.log("Dynamic rules = %r" % drules)
def completeUpgrade(self, mounts, prev_install, target_disk, backup_partnum, admin_iface, admin_bridge, admin_config): util.assertDir(os.path.join(mounts['root'], "var/xapi")) util.assertDir(os.path.join(mounts['root'], "etc/xensource")) Upgrader.completeUpgrade(self, mounts, target_disk, backup_partnum) if not os.path.exists(os.path.join(mounts['root'], constants.DBCACHE)): # upgrade from 5.5, generate dbcache save_dir = os.path.join(mounts['root'], constants.FIRSTBOOT_DATA_DIR, 'initial-ifcfg') util.assertDir(save_dir) dbcache_file = os.path.join(mounts['root'], constants.DBCACHE) dbcache_fd = open(dbcache_file, 'w') network_uid = util.getUUID() dbcache_fd.write('<?xml version="1.0" ?>\n<xenserver-network-configuration>\n') if admin_iface.startswith('bond'): top_pif_uid = bond_pif_uid = util.getUUID() bond_uid = util.getUUID() # find slaves of this bond and write PIFs for them slaves = [] for file in [ f for f in os.listdir(os.path.join(mounts['root'], constants.NET_SCR_DIR)) if re.match('ifcfg-eth[0-9]+$', f) ]: slavecfg = util.readKeyValueFile(os.path.join(mounts['root'], constants.NET_SCR_DIR, file), strip_quotes = False) if slavecfg.has_key('MASTER') and slavecfg['MASTER'] == admin_iface: slave_uid = util.getUUID() slave_net_uid = util.getUUID() slaves.append(slave_uid) slave = NetInterface.loadFromIfcfg(os.path.join(mounts['root'], constants.NET_SCR_DIR, file)) slave.writePif(slavecfg['DEVICE'], dbcache_fd, slave_uid, slave_net_uid, ('slave-of', bond_uid)) # locate bridge that has this interface as its PIFDEV bridge = None for file in [ f for f in os.listdir(os.path.join(mounts['root'], constants.NET_SCR_DIR)) if re.match('ifcfg-xenbr[0-9]+$', f) ]: brcfg = util.readKeyValueFile(os.path.join(mounts['root'], constants.NET_SCR_DIR, file), strip_quotes = False) if brcfg.has_key('PIFDEV') and brcfg['PIFDEV'] == slavecfg['DEVICE']: bridge = brcfg['DEVICE'] break assert bridge dbcache_fd.write('\t<network ref="OpaqueRef:%s">\n' % slave_net_uid) dbcache_fd.write('\t\t<uuid>%sSlaveNetwork</uuid>\n' % slavecfg['DEVICE']) dbcache_fd.write('\t\t<PIFs>\n\t\t\t<PIF>OpaqueRef:%s</PIF>\n\t\t</PIFs>\n' % slave_uid) dbcache_fd.write('\t\t<bridge>%s</bridge>\n' % bridge) dbcache_fd.write('\t\t<other_config/>\n\t</network>\n') # write bond dbcache_fd.write('\t<bond ref="OpaqueRef:%s">\n' % bond_uid) dbcache_fd.write('\t\t<master>OpaqueRef:%s</master>\n' % bond_pif_uid) dbcache_fd.write('\t\t<uuid>InitialManagementBond</uuid>\n\t\t<slaves>\n') for slave_uid in slaves: dbcache_fd.write('\t\t\t<slave>OpaqueRef:%s</slave>\n' % slave_uid) dbcache_fd.write('\t\t</slaves>\n\t</bond>\n') # write bond PIF admin_config.writePif(admin_iface, dbcache_fd, bond_pif_uid, network_uid, ('master-of', bond_uid)) else: top_pif_uid = util.getUUID() # write PIF admin_config.writePif(admin_iface, dbcache_fd, top_pif_uid, network_uid) dbcache_fd.write('\t<network ref="OpaqueRef:%s">\n' % network_uid) dbcache_fd.write('\t\t<uuid>InitialManagementNetwork</uuid>\n') dbcache_fd.write('\t\t<PIFs>\n\t\t\t<PIF>OpaqueRef:%s</PIF>\n\t\t</PIFs>\n' % top_pif_uid) dbcache_fd.write('\t\t<bridge>%s</bridge>\n' % admin_bridge) dbcache_fd.write('\t\t<other_config/>\n\t</network>\n') dbcache_fd.write('</xenserver-network-configuration>\n') dbcache_fd.close() util.runCmd2(['cp', '-p', dbcache_file, save_dir]) else: # upgrade from 5.6 changed = False dbcache_file = os.path.join(mounts['root'], constants.DBCACHE) rdbcache_fd = open(dbcache_file) wdbcache_fd = open(dbcache_file + '.new', 'w') for line in rdbcache_fd: wdbcache_fd.write(line) if '<pif ref=' in line: wdbcache_fd.write("\t\t<tunnel_access_PIF_of/>\n") changed = True rdbcache_fd.close() wdbcache_fd.close() if changed: os.rename(dbcache_file + '.new', dbcache_file) else: os.remove(dbcache_file + '.new') v = Version(prev_install.version.ver) f = open(os.path.join(mounts['root'], 'var/tmp/.previousVersion'), 'w') f.write("PRODUCT_VERSION='%s'\n" % v) f.close() state = open(os.path.join(mounts['root'], constants.FIRSTBOOT_DATA_DIR, 'host.conf'), 'w') print >>state, "UPGRADE=true" state.close() # CP-1508: preserve AD service state ad_on = False try: fh = open(os.path.join(mounts['root'], 'etc/nsswitch.conf'), 'r') for line in fh: if line.startswith('passwd:') and 'lsass' in line: ad_on = True break fh.close() except: pass if ad_on: for service in ['dcerpd', 'eventlogd', 'netlogond', 'npcmuxd', 'lsassd']: util.runCmd2(['chroot', mounts['root'], 'chkconfig', '--add', service]) # EA-1069: create interface-rename state from old xapi database if it doesnt currently exist (static-rules.conf) if not os.path.exists(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/static-rules.conf')): static_text = ( "# Static rules. Autogenerated by the installer from either the answerfile or from previous install\n" "# WARNING - rules in this file override the 'lastboot' assignment of names,\n" "# so editing it may cause unexpected renaming on next boot\n\n" "# Rules are of the form:\n" "# target name: id method = \"value\"\n\n" "# target name must be in the form eth*\n" "# id methods are:\n" "# mac: value should be the mac address of a device (e.g. DE:AD:C0:DE:00:00)\n" "# pci: value should be the pci bus location of the device (e.g. 0000:01:01.1)\n" "# ppn: value should be the result of the biosdevname physical naming policy of a device (e.g. pci1p1)\n" "# label: value should be the SMBios label of a device (for SMBios 2.6 or above)\n") if not os.path.exists(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/.from_install/')): os.makedirs(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/.from_install/'), 0775) fout1 = open(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/static-rules.conf'), "w") fout1.write(static_text) fout1.close() fout2 = open(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/.from_install/static-rules.conf'), "w") fout2.write(static_text) fout2.close() bdn = BiosDevName() bdn.run() devices = bdn.devices # this is a dirty hack but I cant think of much better dbcache = open(os.path.join(mounts['root'], constants.DBCACHE), "r") past_devs = [] mac_next = False eth_next = False for line in ( x.strip() for x in dbcache ): if mac_next: past_devs.append([line.upper()]) mac_next = False continue if eth_next: for bdev in devices: if bdev.get('Assigned MAC', None) == past_devs[-1][0] and 'Bus Info' in bdev: past_devs[-1].extend([bdev['Bus Info'], line]) break eth_next = False continue if line == "<MAC>": mac_next = True continue if line == "<device>": eth_next = True dbcache.close() def jsonify(mac, pci, dev): return '[ "%s", "%s", "%s" ]' % (mac, pci, dev) dynamic_text = ("# Automatically adjusted file. Do not edit unless you are certain you know how to\n") dynamic_text += '{"lastboot":[%s],"old":[]}' % (','.join(map(lambda x: jsonify(*x), (x for x in past_devs if len(x) == 3))), ) fout3 = open(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/dynamic-rules.json'), "w") fout3.write(dynamic_text) fout3.close() fout4 = open(os.path.join(mounts['root'], 'etc/sysconfig/network-scripts/interface-rename-data/.from_install/dynamic-rules.json'), "w") fout4.write(dynamic_text) fout4.close() if Version(prev_install.version.ver) < product.THIS_PRODUCT_VERSION: # set journalling option on EXT local SRs l = LVMTool() for lv in l.lvs: if lv['vg_name'].startswith(l.VG_EXT_SR_PREFIX): l.activateVG(lv['vg_name']) path = '/dev/mapper/%s-%s' % (lv['vg_name'].replace('-', '--'), lv['lv_name'].replace('-', '--')) xelogging.log("Setting ordered on " + path) util.runCmd2(['tune2fs', '-o', 'journal_data_ordered', path]) l.deactivateVG(lv['vg_name'])