예제 #1
0
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, [])
예제 #2
0
    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)
예제 #3
0
    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)