def scanForRaid(drives, degradedOk=False): """Scans for dmraid devices on drives. drives is a list of device names. Returns a list of (raidSet, parentRaidSet, devices, level, totalDisks) tuples. """ log.debug("scanning for dmraid on drives %s" % (drives,)) probeDrives = [] for d in drives: dp = "/dev/" + d isys.makeDevInode(d, dp) probeDrives.append(dp) dp = "/tmp/" + d isys.makeDevInode(d, dp) dmsets = [] def nonDegraded(rs): log.debug("got raidset %s (%s)" % (rs, string.join(rs.member_devpaths))) log.debug(" valid: %s found_devs: %s total_devs: %s" % (rs.valid, rs.rs.found_devs, rs.rs.total_devs)) if not rs.valid and not degradedOk: log.warning("raid %s (%s) is degraded" % (rs, rs.name)) #raise DegradedRaidWarning, rs return False return True raidsets = filter(nonDegraded, block.getRaidSets(probeDrives) or []) def updateName(rs): if dmNameUpdates.has_key(rs.name): rs.set_name(dmNameUpdates[rs.name]) cacheDrives.add(rs) return rs return reduce(lambda x,y: x + [updateName(y),], raidsets, [])
def populate(self, nonraids, mpaths, raids, activeByDefault=False): def _addTuple(tuple): global totalDevices, totalSize global selectedDevices, selectedSize added = False self.store.append(None, tuple) for pg in self.pages: if pg.cb.isMember(tuple[0]): added = True pg.cb.addToUI(tuple) # Only update the size label if this device was added to any pages. # This prevents situations where we're only displaying the basic # filter that has one disk, but there are several advanced disks # in the store that cannot be seen. if added: totalDevices += 1 totalSize += tuple[0]["XXX_SIZE"] if tuple[ACTIVE_COL]: selectedDevices += 1 selectedSize += tuple[0]["XXX_SIZE"] def _isProtected(info): protectedNames = map(udev_resolve_devspec, self.anaconda.protected) sysfs_path = udev_device_get_sysfs_path(info) for protected in protectedNames: _p = "/sys/%s/%s" % (sysfs_path, protected) if os.path.exists(os.path.normpath(_p)): return True return False def _active(info): if _isProtected(info) or activeByDefault: return True name = udev_device_get_name(info) if self.anaconda.storage.exclusiveDisks and \ name in self.anaconda.storage.exclusiveDisks: return True elif self.anaconda.storage.ignoredDisks and \ name not in self.anaconda.storage.ignoredDisks: return True else: return False for d in nonraids: name = udev_device_get_name(d) # We aren't guaranteed to be able to get a device. In # particular, built-in USB flash readers show up as devices but # do not always have any media present, so parted won't be able # to find a device. try: partedDevice = parted.Device(path="/dev/" + name) except (_ped.IOException, _ped.DeviceException): continue d["XXX_SIZE"] = int(partedDevice.getSize()) # cciss controllers, without any sets defined, show up as a 0 size # blockdev, ignore these if d["XXX_SIZE"] == 0: continue # This isn't so great, but iSCSI and s390 devices have an ID_PATH # that contains a lot of useful identifying info, so that should be # displayed instead of a blank WWID. if udev_device_is_iscsi(d) or udev_device_is_dasd( d) or udev_device_is_zfcp(d): ident = udev_device_get_path(d) else: ident = udev_device_get_wwid(d) tuple = (d, True, _active(d), _isProtected(d), name, partedDevice.model, str(d["XXX_SIZE"]) + " MB", udev_device_get_vendor(d), udev_device_get_bus(d), udev_device_get_serial(d), ident, "", "", "", "") _addTuple(tuple) if raids and flags.dmraid: used_raidmembers = [] for rs in block.getRaidSets(): # dmraid does everything in sectors size = (rs.rs.sectors * 512) / (1024.0 * 1024.0) fstype = "" # get_members also returns subsets with layered raids, we only # want the devices members = filter(lambda m: isinstance(m, block.device.RaidDev), list(rs.get_members())) members = map(lambda m: m.get_devpath(), members) for d in raids: if udev_device_get_name(d) in members: fstype = udev_device_get_format(d) sysfs_path = udev_device_get_sysfs_path(d) break # Skip this set if none of its members are in the raids list if not fstype: continue used_raidmembers.extend(members) # biosraid devices don't really get udev data, at least not in a # a way that's useful to the filtering UI. So we need to fake # that data now so we have something to put into the store. data = { "XXX_SIZE": size, "ID_FS_TYPE": fstype, "DM_NAME": rs.name, "name": rs.name, "sysfs_path": sysfs_path } model = "BIOS RAID set (%s)" % rs.rs.set_type tuple = (data, True, _active(data), _isProtected(data), rs.name, model, str(size) + " MB", "", "", "", "", "", "", "", "") _addTuple(tuple) unused_raidmembers = [] for d in raids: if udev_device_get_name(d) not in used_raidmembers: unused_raidmembers.append(udev_device_get_name(d)) self.anaconda.intf.unusedRaidMembersWarning(unused_raidmembers) for mpath in mpaths: # We only need to grab information from the first device in the set. name = udev_device_get_name(mpath[0]) try: partedDevice = parted.Device(path="/dev/" + name) except (_ped.IOException, _ped.DeviceException): continue mpath[0]["XXX_SIZE"] = int(partedDevice.getSize()) model = partedDevice.model # However, we do need all the paths making up this multipath set. paths = "\n".join(map(udev_device_get_name, mpath)) # We use a copy here, so as to not modify the original udev info # dict as that would break NameCache matching data = mpath[0].copy() data["name"] = udev_device_get_multipath_name(mpath[0]) tuple = (data, True, _active(data), _isProtected(data), udev_device_get_multipath_name(mpath[0]), model, str(mpath[0]["XXX_SIZE"]) + " MB", udev_device_get_vendor(mpath[0]), udev_device_get_bus(mpath[0]), udev_device_get_serial(mpath[0]), udev_device_get_wwid(mpath[0]), paths, "", "", "") _addTuple(tuple)
def populate(self, nonraids, mpaths, raids, activeByDefault=False): def _addTuple(tuple): global totalDevices, totalSize global selectedDevices, selectedSize added = False self.store.append(None, tuple) for pg in self.pages: if pg.cb.isMember(tuple[0]): added = True pg.cb.addToUI(tuple) # Only update the size label if this device was added to any pages. # This prevents situations where we're only displaying the basic # filter that has one disk, but there are several advanced disks # in the store that cannot be seen. if added: totalDevices += 1 totalSize += tuple[0]["XXX_SIZE"] if tuple[2]: selectedDevices += 1 selectedSize += tuple[0]["XXX_SIZE"] def _isProtected(info): protectedNames = map(udev_resolve_devspec, self.anaconda.protected) sysfs_path = udev_device_get_sysfs_path(info) for protected in protectedNames: _p = "/sys/%s/%s" % (sysfs_path, protected) if os.path.exists(os.path.normpath(_p)): return True return False def _active(info): if activeByDefault or _isProtected(info): return True name = udev_device_get_name(info) if self.anaconda.id.storage.exclusiveDisks and \ name in self.anaconda.id.storage.exclusiveDisks: return True elif self.anaconda.id.storage.ignoredDisks and \ name not in self.anaconda.id.storage.ignoredDisks: return True else: return False for d in nonraids: name = udev_device_get_name(d) # We aren't guaranteed to be able to get a device. In # particular, built-in USB flash readers show up as devices but # do not always have any media present, so parted won't be able # to find a device. try: partedDevice = parted.Device(path="/dev/" + name) except (_ped.IOException, _ped.DeviceException): continue d["XXX_SIZE"] = long(partedDevice.getSize()) # This isn't so great, but iSCSI and s390 devices have an ID_PATH # that contains a lot of useful identifying info, so that should be # displayed instead of a blank WWID. if udev_device_is_iscsi(d) or udev_device_is_dasd(d) or udev_device_is_zfcp(d): ident = udev_device_get_path(d) else: ident = udev_device_get_wwid(d) tuple = (d, True, _active(d), _isProtected(d), name, partedDevice.model, long(d["XXX_SIZE"]), udev_device_get_vendor(d), udev_device_get_bus(d), udev_device_get_serial(d), ident, "", "", "", "") _addTuple(tuple) if raids and flags.dmraid: used_raidmembers = [] for rs in block.getRaidSets(): # dmraid does everything in sectors size = (rs.rs.sectors * 512) / (1024.0 * 1024.0) fstype = "" # get_members also returns subsets with layered raids, we only # want the devices members = filter(lambda m: isinstance(m, block.device.RaidDev), list(rs.get_members())) members = map(lambda m: m.get_devpath(), members) for d in raids: if udev_device_get_name(d) in members: fstype = udev_device_get_format(d) sysfs_path = udev_device_get_sysfs_path(d) break # Skip this set if none of its members are in the raids list if not fstype: continue used_raidmembers.extend(members) # biosraid devices don't really get udev data, at least not in a # a way that's useful to the filtering UI. So we need to fake # that data now so we have something to put into the store. data = {"XXX_SIZE": size, "ID_FS_TYPE": fstype, "DM_NAME": rs.name, "name": rs.name, "sysfs_path": sysfs_path} model = "BIOS RAID set (%s)" % rs.rs.set_type tuple = (data, True, _active(data), _isProtected(data), rs.name, model, long(size), "", "", "", "", "\n".join(members), "", "", "") _addTuple(tuple) unused_raidmembers = [] for d in raids: if udev_device_get_name(d) not in used_raidmembers: unused_raidmembers.append(udev_device_get_name(d)) self.anaconda.intf.unusedRaidMembersWarning(unused_raidmembers) for mpath in mpaths: # We only need to grab information from the first device in the set. name = udev_device_get_name(mpath[0]) try: partedDevice = parted.Device(path="/dev/" + name) except (_ped.IOException, _ped.DeviceException): continue mpath[0]["XXX_SIZE"] = long(partedDevice.getSize()) model = partedDevice.model # However, we do need all the paths making up this multipath set. paths = "\n".join(map(udev_device_get_name, mpath)) # We use a copy here, so as to not modify the original udev info # dict as that would break NameCache matching data = mpath[0].copy() data["name"] = udev_device_get_multipath_name(mpath[0]) tuple = (data, True, _active(data), _isProtected(data), udev_device_get_multipath_name(mpath[0]), model, long(mpath[0]["XXX_SIZE"]), udev_device_get_vendor(mpath[0]), udev_device_get_bus(mpath[0]), udev_device_get_serial(mpath[0]), udev_device_get_wwid(mpath[0]), paths, "", "", "") _addTuple(tuple)