def make_pci_links(self): links = [] device_root = "/sys/devices/" prelinks = [] bases = [] trees = {} for dir in listdir(device_root): if dir[:8] == "pci0000:": bases.append(dir) for base in bases: trees[base] = self._walk(device_root + base + "/") trees[base].reverse() # get the tree in the order we're expecting. for base in bases: ct = 0 for pl in trees[base]: pl = base + "/" + pl trees[base][ct] = pl ct += 1 prelinks.extend(trees[base]) base_len = len(bases) for node in prelinks: fail = self._gen_pci_tup(device_root, node) if fail == "": continue (vend, id, match, str, mem) = fail link = Pci_link() link.pci_subid = vend + ":" + id if base_len == 2: link.tnv_string = match else: link.tnv_string = match[3:] link.memory_base = mem links.append(link) return links
def make_pci_links(self): links = [] # first, scan PCI bus device_root = '/sys/devices/' prelinks = [] trees = {} bases = [ d for d in listdir(device_root) if d.startswith('pci0000:') ] for base in bases: trees[base] = self._walk(device_root+base+'/') # put everything into a standard order trees[base].sort() for base in bases: ct = 0 for pl in trees[base]: pl = base + '/' + pl trees[base][ct] = pl ct += 1 prelinks.extend(trees[base]) base_len = len(bases) for node in prelinks: fail = self._gen_pci_tup(device_root, node) if fail == '': continue (vend, id, match, str, mem) = fail link = Pci_link() link.bdf = str link.pci_subid = vend+':'+id if base_len > 1: link.tnv_string = match else: link.tnv_string = match[3:] link.memory_base = mem links.append(link) # then, check vmbus (hyper-v) dev_bus = '/sys/bus/vmbus/drivers/hv_netvsc/' if isdir(dev_bus): hv_links = [] for dev_code in listdir(dev_bus): if dev_code.startswith('vmbus_'): dev_path = dev_bus + dev_code ### dev_net = dev_path + '/net/' ### for dev_label in listdir(dev_net): ### dev_mac = self._read_strip(dev_net + dev_label + '/address') # hyper-v NICs lack subsystem_device, but have a consistent UUID dev_class = self._read_uuid(dev_path + '/class_id') # hyper-v dev_num assignment varies, but its *order* is persistent dev_num = self._read_strip(dev_path + '/id') # hyper-v vmbus devices lack /resource, so key on /device_id dev_uuid = self._read_uuid(dev_path + '/device_id') # hyper-v NICs lack subsystem_vendor, but functionally it # just has to match the NIC's name_keys in config.xml dev_vendor = 'hyperv' dev_link = Pci_link() dev_link.pci_subid = dev_vendor + ':' + dev_class # Pci_link.tnv_string must match the motherboard's slots' pattern # as defined in bus_number_pattern in config.xml. for hyper-v, # slots are just logical constructs grouping pairs of NICs. # only legacy hyper-v NICs are onboard, so both pri and aux should # logically occupy slots 0 and 1. therefore we add inpath pairs # to slots 2/3, 4/5, etc. we don't necessarily encounter vmbus # NICs in ascending order, so for now we just save /device_id dev_link.tnv_string = 'hyperv.' + dev_num # there's no vmbus equivalent of PCI's /resource; we instead use # a unique hex number to identify and distinguish NICs reliably dev_link.memory_base = dev_uuid hv_links.append(dev_link) # NIC id *order* is consistent; sort in case we picked them up differently hv_links.sort(key=lambda x: x.tnv_string) i = 0 # assign them to slots in successive pairs for dev_link in hv_links: dev_link.tnv_string = "hyperv.{0:02d}".format(i) i += 1 links.append(dev_link) return links