FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Debian > Debian Development

 
 
LinkBack Thread Tools
 
Old 03-06-2009, 02:53 PM
Joel Granados Moreno
 
Default Add dmraid functionality to new storage code.

* storage/devices.py (DMRaidArrayDevice): Complete the DMRaidArrayDevice
class.
* storage/devices.py (PartitionDeviceFactory): When creating a
partition we need to decide, based on the device holding the
partition, what type of partition class will be returned.
* storage/devices.py (PartitionDevice): When setting the disk we must be
careful to change stuff accordingly.

* storage/devicetree.py (addUdevDevice): Handle the creation of the
dmraid device and its members in the addUdeveDevice function.

* storage/formats/dmraid.py (DMRaidMember): Complete the format that
handles devices being members of a dmraid array.
* storage/udev.py (udev_device_is_dmraid): add a function that
recognizes dmraid devices from the provided info list.

* storage/udev.py (udev_device_get_dmraid_partition_disk): function that
gets the disk string from partition info.
* storage/udev.py (udev_device_is_dmraid_partition): function that
checks for dmraid partitions.

* storage/__init__.py (disks(self)): return a list of disks from the
internal attribute.
* storage/__init__.py (Storage.disks): we really want to make sure we
return all the objects that comply with the DiskDevice interface
(inheret from DiskDevice)
* storage/__init__.py (Storage.partitions): Same as above but for
PartitionDevice.

* iw/autopart_type (PartitionTypeWindow(InstallWindow)): use disk.name
instead of munging the first 5 characters of the path.

* storage/partitioning (newPartition): Use the new partition factory to
create a partition.
---
iw/autopart_type.py | 9 +--
iw/partition_gui.py | 8 +-
storage/__init__.py | 22 ++++-
storage/devices.py | 202 +++++++++++++++++++++++++++++++++++++++++----
storage/devicetree.py | 92 +++++++++++++++++---
storage/formats/dmraid.py | 23 ++++--
storage/partitioning.py | 4 +-
storage/udev.py | 33 ++++++++
8 files changed, 341 insertions(+), 52 deletions(-)

diff --git a/iw/autopart_type.py b/iw/autopart_type.py
index ba8c0dc..700d7da 100644
--- a/iw/autopart_type.py
+++ b/iw/autopart_type.py
@@ -381,14 +381,11 @@ class PartitionTypeWindow(InstallWindow):
else:
defaultBoot = None
for disk in self.storage.disks:
- partedDisk = disk.partedDisk
- if partedDisk.device.path[5:] not in self.anaconda.id.bootloader.drivelist:
+ if disk.name not in self.anaconda.id.bootloader.drivelist:
continue
- size = partedDisk.device.getSize(unit="MB")
- dispstr = "%s %8.0f MB %s" %(partedDisk.device.path[5:],
- size, partedDisk.device.model)
+ dispstr = "%s %8.0f MB %s" %(disk.name, disk.size, disk.partedDisk.device.model)
i = bootstore.append(None)
- bootstore[i] = (dispstr, partedDisk.device.path[5:])
+ bootstore[i] = (dispstr, disk.name)
if disk.name == defaultBoot:
self.bootcombo.set_active_iter(i)

diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index c704b08..9dae436 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py
@@ -142,12 +142,12 @@ class DiskStripeSlice:
if self.partition.type & parted.PARTITION_FREESPACE:
rc = "Free
"
else:
- rc = "%s
" % (self.partition.getDeviceNodeName(),)
+ rc = "%s
" % (self.partition.getDeviceNodeName().split("/")[-1],)
rc = rc + "%Ld MB" % (self.partition.getSize(unit="MB"),)
return rc

def getDeviceName(self):
- return self.partition.getDeviceNodeName()
+ return self.partition.getDeviceNodeName().split("/")[-1]

def update(self):
disk = self.parent.getDisk()
@@ -808,7 +808,7 @@ class PartitionWindow(InstallWindow):
part = part.nextPartition()
continue

- partName = part.getDeviceNodeName()
+ partName = part.getDeviceNodeName().split("/")[-1]
device = self.storage.devicetree.getDeviceByName(partName)
if not device and not part.type & parted.PARTITION_FREESPACE:
raise RuntimeError("can't find partition %s in device"
@@ -1054,7 +1054,7 @@ class PartitionWindow(InstallWindow):
self.editLVMVolumeGroup(device)
elif device.type == "lvmlv":
self.editLVMVolumeGroup(device)
- elif device.type == "partition":
+ elif isinstance(device, storage.devices.PartitionDevice):
self.editPartition(device)

# isNew implies that this request has never been successfully used before
diff --git a/storage/__init__.py b/storage/__init__.py
index 7bac367..6c241c2 100644
--- a/storage/__init__.py
+++ b/storage/__init__.py
@@ -238,7 +238,11 @@ class Storage(object):
does not necessarily reflect the actual on-disk state of the
system's disks.
"""
- disks = self.devicetree.getDevicesByType("disk")
+ disks = []
+ devices = self.devicetree.devices
+ for d in devices:
+ if isinstance(devices[d], DiskDevice):
+ disks.append(devices[d])
disks.sort(key=lambda d: d.name)
return disks

@@ -250,7 +254,11 @@ class Storage(object):
does not necessarily reflect the actual on-disk state of the
system's disks.
"""
- partitions = self.devicetree.getDevicesByType("partition")
+ partitions = []
+ devices = self.devicetree.devices
+ for d in devices:
+ if isinstance(devices[d], PartitionDevice):
+ partitions.append(devices[d])
partitions.sort(key=lambda d: d.name)
return partitions

@@ -423,7 +431,7 @@ class Storage(object):
if device.name in self.protectedPartitions:
return _("This partition is holding the data for the hard "
"drive install.")
- elif device.type == "partition" and device.isProtected:
+ elif isinstance(device, PartitionDevice) and device.isProtected:
# LDL formatted DASDs always have one partition, you'd have to
# reformat the DASD in CDL mode to get rid of it
return _("You cannot delete a partition of a LDL formatted "
@@ -445,7 +453,7 @@ class Storage(object):
else:
return _("This device is part of a LVM volume "
"group.")
- elif device.type == "partition" and device.isExtended:
+ elif isinstance(device, PartitionDevice) and device.isExtended:
reasons = {}
for dep in self.deviceDeps(device):
reason = self.deviceImmutable(dep)
@@ -473,13 +481,17 @@ class Storage(object):

if kwargs.has_key("disks"):
parents = kwargs.pop("disks")
+ if isinstance(parents, Device):
+ kwargs["parents"] = [parents]
+ else:
+ kwargs["parents"] = parents

if kwargs.has_key("name"):
name = kwargs.pop("name")
else:
name = "req%d" % self.nextID

- return PartitionDevice(name, *args, **kwargs)
+ return PartitionDeviceFactory(name, *args, **kwargs)

def newMDArray(self, *args, **kwargs):
""" Return a new MDRaidArrayDevice instance for configuring. """
diff --git a/storage/devices.py b/storage/devices.py
index 84cfe1b..dd5a4f1 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -127,6 +127,74 @@ def get_device_majors():
return majors
device_majors = get_device_majors()

+def PartitionDeviceFactory(*args, **kwargs):
+ """This will decide what PartitionDevice class will be used.
+
+ Arguments:
+
+ name -- the device name (generally a device node's basename)
+
+ Keyword Arguments:
+
+ exists -- indicates whether this is an existing device
+ format -- the device's format (DeviceFormat instance)
+
+ For existing partitions:
+
+ parents -- the disk that contains this partition
+ major -- the device major
+ minor -- the device minor
+ sysfsPath -- sysfs device path
+
+ For new partitions:
+
+ partType -- primary,extended,&c (as parted constant)
+ grow -- whether or not to grow the partition
+ maxsize -- max size for growable partitions (in MB)
+ size -- the device's size (in MB)
+ bootable -- whether the partition is bootable
+ parents -- a list of potential containing disks
+
+ The decision will be made base on finding the disk by name
+ """
+ # FIXME: PRePBootDevice should be here somehow.!!!
+ roots = ["/dev", "/dev/mapper"]
+ # firs lets normalize the name
+ norm_name = args[0].split("/")[-1]
+
+ # We look for the disk in /dev. From PartitionDevice its the [0] one.
+ if (not kwargs.has_key("parents")) or
+ (kwargs.has_key("exists") and not kwargs["exists"]):
+ # Cant really choose a good type of class, default to PartitionDevice
+ # This will be considered as a request.
+ return PartitionDevice(*args, **kwargs)
+ else:
+ parents = kwargs["parents"]
+ if isinstance(parents, Device):
+ parents = [parents]
+ # we receive a list of parents. look for the disk that contains the name
+ # if we dont find the name we will return PartitionDevice and let it raise
+ # the exception.
+ for root in roots:
+ for parent in parents:
+ path = os.path.join(root,norm_name)
+ log.debug("looking up parted Partition: %s" % path)
+ part = parent.partedDisk.getPartitionByPath(path)
+ if not part:
+ continue
+ else:
+ # we have found a part. no make the decision based on path
+ if path.startswith(roots[1]):
+ #we create a DMPartition
+ return DMRaidPartitionDevice(*args, **kwargs)
+ elif path.startswith(roots[0]):
+ # make sure that the parent is consistent
+ kwargs["parents"] = [parent]
+ return PartitionDevice(*args, **kwargs)
+
+ # If we get here, we did not find anything.
+ return PartitionDevice(*args, **kwargs)
+
class Device(object):
""" A generic device.

@@ -861,14 +929,14 @@ class PartitionDevice(StorageDevice):
# no need to clobber our name
else:
self._partedPartition = partition
- self._name = partition.getDeviceNodeName()
+ self._name = partition.getDeviceNodeName().split("/")[-1]

partedPartition = property(lambda d: d._getPartedPartition(),
lambda d,p: d._setPartedPartition(p))

def dependsOn(self, dep):
""" Return True if this device depends on dep. """
- if dep.type == "partition" and dep.isExtended and self.isLogical:
+ if isinstance(dep, PartitionDevice) and dep.isExtended and self.isLogical:
return True

return Device.dependsOn(self, dep)
@@ -1051,7 +1119,7 @@ class PartitionDevice(StorageDevice):
geometry.length = new_length

def _getDisk(self):
- """ The disk that contains this partition. """
+ """ The disk that contains this partition."""
try:
disk = self.parents[0]
except IndexError:
@@ -1059,12 +1127,27 @@ class PartitionDevice(StorageDevice):
return disk

def _setDisk(self, disk):
+ """Change the parent.
+
+ Setting up a disk is not trivial. It has the potential to change
+ the underlying object. If necessary we must also change this object.
+ """
log_method_call(self, self.name, old=self.disk, new=disk)
if self.disk:
self.disk.removeChild()

self.parents = [disk]
disk.addChild()
+ if isinstance(disk, DMRaidArrayDevice):
+ # modify the partition so it can look like the DMRaidPartitionDevice.
+
+ self._type = "dmraid partition"
+ self._packages = ["dmraid"]
+ self.devDir = "/dev/mapper"
+ self.updateSysfsPath = DMDevice.updateSysfsPath
+ self.getDMNode = DMDevice.getDMNode
+
+

disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))

@@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
self.exists = False


-class DMRaidArrayDevice(DMDevice):
+class DMRaidArrayDevice(DiskDevice):
""" A dmraid (device-mapper RAID) device """
_type = "dm-raid array"
_packages = ["dmraid"]
+ devDir = "/dev/mapper"

- def __init__(self, name, format=None, size=None,
- exists=None, parents=None, sysfsPath='):
+ def __init__(self, name, raidSet=None, level=None, format=None, size=None,
+ major=None, minor=None, parents=None, sysfsPath='):
""" Create a DMRaidArrayDevice instance.

Arguments:

- name -- the device name (generally a device node's basename)
+ name -- the dmraid name also the device node's basename

Keyword Arguments:

+ raidSet -- the RaidSet object from block
+ level -- the type of dmraid
parents -- a list of the member devices
sysfsPath -- sysfs device path
size -- the device's size
format -- a DeviceFormat instance
- exists -- indicates whether this is an existing device
"""
if isinstance(parents, list):
for parent in parents:
if not parent.format or parent.format.type != "dmraidmember":
raise ValueError("parent devices must contain dmraidmember format")
- DMDevice.__init__(self, name, format=format, size=size,
- parents=parents, sysfsPath=sysfsPath,
- exists=exists)
+ DiskDevice.__init__(self, name, format=format, size=size,
+ major=major, minor=minor,
+ parents=parents, sysfsPath=sysfsPath)

- def probe(self):
- """ Probe for any missing information about this device.
+ self.formatClass = get_device_format_class("dmraidmember")
+ if not self.formatClass:
+ raise DeviceError("cannot find class for 'dmraidmember'")

- size
+
+ self._raidSet = raidSet
+ self._level = level
+
+ @property
+ def raidSet(self):
+ return self._raidSet
+
+ @raidSet.setter
+ def raidSet(self, val):
+ # If we change self._raidSet, parents list will be invalid.
+ # Don't allow the change.
+ pass
+
+ def _addDevice(self, device):
+ """ Add a new member device to the array.
+
+ XXX This is for use when probing devices, not for modification
+ of arrays.
"""
- raise NotImplementedError("probe method not defined for DMRaidArrayDevice")
+ log_method_call(self, self.name, device=device.name, status=self.status)
+
+ if not self.exists:
+ raise DeviceError("device has not been created")
+
+ if not isinstance(device.format, self.formatClass):
+ raise ValueError("invalid device format for dmraid member")
+
+ if device in self.members:
+ raise ValueError("device is already a member of this array")
+
+ # we added it, so now set up the relations
+ self.devices.append(device)
+ device.addChild()
+
+ @property
+ def members(self):
+ return self.parents
+
+ @property
+ def devices(self):
+ """ Return a list of this array's member device instances. """
+ return self.parents
+
+ def activate(self, mknod=True):
+ self._raidSet.activate(mknod=mknod)
+
+ def deactivate(self):
+ self._raidSet.deactivate()
+
+ # We are more like a disk then a dmdevice, but we are still a dmdevice,
+ # so we need to "inherit" some functions from dmdevice
+ def updateSysfsPath(self):
+ DMDevice.updateSysfsPath(self)
+
+ def getDMNode(self):
+ DMDevice.getDMNode(self)
+
+ def teardown(self, recursive=None):
+ # avoid DiskDevice's overriding of teardown()
+ StorageDevice.teardown(self, recursive)
+
+
+class DMRaidPartitionDevice(PartitionDevice):
+ """ A disk partition in a dmraid array, identical to a general
+ PartitionDevice, except for the device path and sysfs path
+ """
+ _type = "dmraid partition"
+ _packages = ["dmraid"]
+ devDir = "/dev/mapper"
+
+ def __init__(self, name, format=None,
+ size=None, grow=False, maxsize=None,
+ major=None, minor=None, bootable=None,
+ sysfsPath=', parents=None, exists=None,
+ partType=None, primary=False):
+ PartitionDevice.__init__(self, name, format=format, size=size,
+ major=major, minor=minor, bootable=bootable,
+ sysfsPath=sysfsPath, parents=parents,
+ exists=exists, partType=partType,
+ primary=primary)
+
+ # We are more like a partition then a dmdevice, but we are still a dmdevice
+ # so we need to "inherit" some functions from dmdevice
+ def updateSysfsPath(self):
+ DMDevice.updateSysfsPath(self)
+
+ def getDMNode(self):
+ DMDevice.getDMNode(self)


class MultipathDevice(DMDevice):
diff --git a/storage/devicetree.py b/storage/devicetree.py
index 3494d5a..a83279d 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -21,6 +21,7 @@
#

import os
+import block

from errors import *
from devices import *
@@ -458,7 +459,7 @@ class DeviceTree(object):
raise ValueError("Cannot remove non-leaf device '%s'" % dev.name)

# if this is a partition we need to remove it from the parted.Disk
- if dev.type == "partition":
+ if isinstance(dev, PartitionDevice):
dev.disk.removePartition(dev)

self._devices.remove(dev)
@@ -558,9 +559,9 @@ class DeviceTree(object):
# special handling for extended partitions since the logical
# partitions and their deps effectively depend on the extended
logicals = []
- if dep.type == "partition" and dep.isExtended:
+ if isinstance(dep, PartitionDevice):
# collect all of the logicals on the same disk
- for part in self.getDevicesByType("partition"):
+ for part in self.getDevicesByInstance(PartitionDevice):
if part.isLogical and part.disk == dep.disk:
logicals.append(part)

@@ -601,6 +602,13 @@ class DeviceTree(object):
# this is a partition on a disk in the ignore list
return True

+ # Ignore partitions found on the raw disks which are part of a
+ # dmraidset
+ for set in self.getDevicesByType("dm-raid array"):
+ for disk in set.parents:
+ if disk.name == os.path.basename(os.path.dirname(sysfs_path)):
+ return True
+
# FIXME: check for virtual devices whose slaves are on the ignore list

def addUdevDevice(self, info):
@@ -667,6 +675,19 @@ class DeviceTree(object):
log.error("failure scanning device %s" % name)
return

+ if device is None and
+ udev_device_is_dmraid_partition(info, self):
+ diskname = udev_device_get_dmraid_partition_disk(info)
+ disk = self.getDeviceByName(diskname)
+ device = PartitionDeviceFactory(name,
+ sysfsPath=sysfs_path,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ exists=True,
+ parents=[disk])
+ self._addDevice(device)
+ #self.ignoredDisks.append(name)
+
# if we get here, we found all of the slave devices and
# something must be wrong -- if all of the slaves are in
# the tree, this device should be as well
@@ -741,6 +762,17 @@ class DeviceTree(object):
minor=udev_device_get_minor(info),
sysfsPath=sysfs_path)
self._addDevice(device)
+ elif udev_device_is_dmraid(info):
+ # This is just temporary as I need to differentiate between the
+ # device that has partitions and device that dont.
+ log.debug("%s is part of a dmraid" % name)
+ device = self.getDeviceByName(name)
+ if device is None:
+ device = StorageDevice(name,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ sysfsPath=sysfs_path, exists=True)
+ self._addDevice(device)
elif udev_device_is_disk(info):
log.debug("%s is a disk" % name)
device = self.getDeviceByName(name)
@@ -793,12 +825,12 @@ class DeviceTree(object):
log.error("failure scanning device %s" % disk_name)
return

- device = PartitionDevice(name,
- sysfsPath=sysfs_path,
- major=udev_device_get_major(info),
- minor=udev_device_get_minor(info),
- exists=True,
- parents=[disk])
+ device = PartitionDeviceFactory(name,
+ sysfsPath=sysfs_path,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ exists=True,
+ parents=[disk])
self._addDevice(device)

#
@@ -824,9 +856,8 @@ class DeviceTree(object):
except KeyError:
log.debug("mdraid member %s has no md uuid" % name)
elif format_type == "isw_raid_member":
- # dmraid
- # TODO: collect name of containing raidset
- # TODO: implement dmraid member format class
+ # We dont add any new args because we intend to use the same
+ # block.RaidSet object for all the related devices.
pass
elif format_type == "LVM2_member":
# lvm
@@ -914,8 +945,38 @@ class DeviceTree(object):
parents=[device])
self._addDevice(md_array)
elif format.type == "dmraidmember":
- # look up or create the dmraid array
- pass
+ major = udev_device_get_major(info)
+ minor = udev_device_get_minor(info)
+ # Have we already created the DMRaidArrayDevice?
+ rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
+ major=major, minor=minor)
+ if rs is None:
+ # FIXME: Should handle not finding a dmriad dev better
+ pass
+
+ dm_array = self.getDeviceByName(rs.name)
+ if dm_array is not None:
+ # We add the new device.
+ dm_array._addDevice(device)
+ else:
+ # Activate the Raid set.
+ rs.activate(mknod=True)
+
+ # Create the DMRaidArray
+ dm_array = DMRaidArrayDevice(rs.name,
+ major=major, minor=minor,
+ raidSet=rs,
+ level=rs.level,
+ parents=[device])
+
+ self._addDevice(dm_array)
+
+ # Use the rs's object on the device.
+ # pyblock can return the memebers of a set and the device has
+ # the attribute to hold it. But ATM we are not really using it.
+ # Commenting this out until we really need it.
+ #device.format.raidmem = block.getMemFromRaidSet(dm_array,
+ # major=major, minor=minor, uuid=uuid, name=name)
elif format.type == "lvmpv":
# lookup/create the VG and LVs
try:
@@ -1077,6 +1138,9 @@ class DeviceTree(object):
# TODO: expand this to catch device format types
return [d for d in self._devices if d.type == device_type]

+ def getDevicesByInstance(self, device_class):
+ return [d for d in self._devices if isinstance(d, device_class)]
+
@property
def devices(self):
""" Dict with device path keys and Device values. """
diff --git a/storage/formats/dmraid.py b/storage/formats/dmraid.py
index d458b45..ef80902 100644
--- a/storage/formats/dmraid.py
+++ b/storage/formats/dmraid.py
@@ -20,6 +20,8 @@
# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
#

+import block
+
from iutil import log_method_call
#from dm import dm_node_from_name
from ..errors import *
@@ -65,25 +67,34 @@ class DMRaidMember(DeviceFormat):

device -- path to the underlying device
uuid -- this format's UUID
- raidSet -- the name of the raidset this member belongs to
exists -- indicates whether this is an existing format

+ On initialization this format is like DeviceFormat
+
"""
log_method_call(self, *args, **kwargs)
DeviceFormat.__init__(self, *args, **kwargs)
-
- self.raidSet = kwargs.get("raidSet")
+
+ # Initialize the attribute that will hold the block object.
+ self._raidmem = None
+
+ @property
+ def raidmem(self):
+ return self._raidmem
+
+ @raidmem.setter
+ def raidmem(self, raidmem):
+ self._raidmem = raidmem

def create(self, *args, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- raise DMRaidMemberError("creation of dmraid members is not supported")
+ raise DMRaidMemberError("creation of dmraid members is non-sense")

def destroy(self, *args, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- raise DMRaidMemberError("destruction of dmraid members is not supported")
-
+ raise DMRaidMemberError("destruction of dmraid members is non-sense")

register_device_format(DMRaidMember)

diff --git a/storage/partitioning.py b/storage/partitioning.py
index d1f2d4d..78929cf 100644
--- a/storage/partitioning.py
+++ b/storage/partitioning.py
@@ -32,7 +32,7 @@ from constants import *

from errors import *
from deviceaction import *
-from devices import PartitionDevice, LUKSDevice
+from devices import PartitionDeviceFactory, LUKSDevice

import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
@@ -530,7 +530,7 @@ def doPartitioning(storage, exclusiveDisks=None):
# that does not exist means leaving self.parents empty and instead
# populating self.req_disks. In this case, we need to skip past
# that since this partition is already defined.
- device = PartitionDevice(extended.getDeviceNodeName(),
+ device = PartitionDeviceFactory(extended.getDeviceNodeName( ),
parents=disk)
device.parents = [disk]
device.partedPartition = extended
diff --git a/storage/udev.py b/storage/udev.py
index 6df00c8..a39b98c 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -270,4 +270,37 @@ def udev_device_get_lv_sizes(info):

return [float(s) / 1024 for s in sizes]

+def udev_device_is_dmraid(info):
+ # Note that this function does *not* identify raid sets.
+ # Tests to see if device is parto of a dmraid set.
+ # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a
+ # string that describes the type of dmraid (isw_raid_member...), I don't
+ # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
+ # dmraid will be everything that is raid and not linux_raid_member
+ if info.has_key("ID_FS_USAGE") and info.has_key("ID_FS_TYPE") and
+ info["ID_FS_USAGE"] == "raid" and
+ info["ID_FS_TYPE"] != "linux_raid_member":
+ return True
+
+ return False
+
+def udev_device_get_dmraid_partition_disk(info):
+ try:
+ p_index = info["DM_NAME"].rindex("p")
+ except:
+ return None
+
+ if not info["DM_NAME"][p_index+1:].isdigit():
+ return None
+
+ return info["DM_NAME"][_index]
+
+def udev_device_is_dmraid_partition(info, devicetree):
+ diskname = udev_device_get_dmraid_partition_disk(info)
+ dmraid_devices = devicetree.getDevicesByType("dm-raid array")
+
+ for device in dmraid_devices:
+ if diskname == device.name:
+ return True

+ return False
--
1.6.0.6

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 03:23 PM
Hans de Goede
 
Default Add dmraid functionality to new storage code.

Joel Granados Moreno wrote:

<huge snip>

> diff --git a/storage/__init__.py b/storage/__init__.py
> index 7bac367..6c241c2 100644
> --- a/storage/__init__.py
> +++ b/storage/__init__.py
> @@ -238,7 +238,11 @@ class Storage(object):
> does not necessarily reflect the actual on-disk state of the
> system's disks.
> """
> - disks = self.devicetree.getDevicesByType("disk")
> + disks = []
> + devices = self.devicetree.devices
> + for d in devices:
> + if isinstance(devices[d], DiskDevice):
> + disks.append(devices[d])
> disks.sort(key=lambda d: d.name)
> return disks
>
> @@ -250,7 +254,11 @@ class Storage(object):
> does not necessarily reflect the actual on-disk state of the
> system's disks.
> """
> - partitions = self.devicetree.getDevicesByType("partition")
> + partitions = []
> + devices = self.devicetree.devices
> + for d in devices:
> + if isinstance(devices[d], PartitionDevice):
> + partitions.append(devices[d])
> partitions.sort(key=lambda d: d.name)
> return partitions
>

We could use the new devicetree.getDevicesByInstance you add in this same patch here instead.

<more snip>


@@ -1059,12 +1127,27 @@ class PartitionDevice(StorageDevice):
return disk

def _setDisk(self, disk):

+ """Change the parent.
+
+ Setting up a disk is not trivial. It has the potential to change
+ the underlying object. If necessary we must also change this object.
+ """
log_method_call(self, self.name, old=self.disk, new=disk)
if self.disk:
self.disk.removeChild()

self.parents = [disk]

disk.addChild()
+ if isinstance(disk, DMRaidArrayDevice):
+ # modify the partition so it can look like the DMRaidPartitionDevice.
+
+ self._type = "dmraid partition"
+ self._packages = ["dmraid"]
+ self.devDir = "/dev/mapper"
+ self.updateSysfsPath = DMDevice.updateSysfsPath
+ self.getDMNode = DMDevice.getDMNode
+
+

disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))




What if we go the other way around so from being a partition on a DMRaidArrayDevice
to one on a regular DiskDevice ?


@@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
self.exists = False


-class DMRaidArrayDevice(DMDevice):

+class DMRaidArrayDevice(DiskDevice):
""" A dmraid (device-mapper RAID) device """
_type = "dm-raid array"
_packages = ["dmraid"]
+ devDir = "/dev/mapper"

- def __init__(self, name, format=None, size=None,

- exists=None, parents=None, sysfsPath='):
+ def __init__(self, name, raidSet=None, level=None, format=None, size=None,
+ major=None, minor=None, parents=None, sysfsPath='):
""" Create a DMRaidArrayDevice instance.

Arguments:

- name -- the device name (generally a device node's basename)

+ name -- the dmraid name also the device node's basename

Keyword Arguments:

+ raidSet -- the RaidSet object from block

+ level -- the type of dmraid
parents -- a list of the member devices
sysfsPath -- sysfs device path
size -- the device's size
format -- a DeviceFormat instance
- exists -- indicates whether this is an existing device
"""
if isinstance(parents, list):
for parent in parents:
if not parent.format or parent.format.type != "dmraidmember":
raise ValueError("parent devices must contain dmraidmember format")
- DMDevice.__init__(self, name, format=format, size=size,
- parents=parents, sysfsPath=sysfsPath,
- exists=exists)
+ DiskDevice.__init__(self, name, format=format, size=size,
+ major=major, minor=minor,
+ parents=parents, sysfsPath=sysfsPath)

- def probe(self):

- """ Probe for any missing information about this device.
+ self.formatClass = get_device_format_class("dmraidmember")
+ if not self.formatClass:
+ raise DeviceError("cannot find class for 'dmraidmember'")

- size

+
+ self._raidSet = raidSet
+ self._level = level
+
+ @property
+ def raidSet(self):
+ return self._raidSet
+
+ @raidSet.setter
+ def raidSet(self, val):
+ # If we change self._raidSet, parents list will be invalid.
+ # Don't allow the change.
+ pass
+


I think you should just omit the setter then, this will cause python to throw an error
rather then to ignore the write silently. I think dlehman made a similar remark to an
earlier version of this patch.

<huge snip>

Regards,

Hans

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 03:38 PM
David Lehman
 
Default Add dmraid functionality to new storage code.

Overall it is good, but there are a couple of things you need to fix.
See below.

> diff --git a/storage/devices.py b/storage/devices.py
> index 84cfe1b..dd5a4f1 100644
> --- a/storage/devices.py
> +++ b/storage/devices.py
> @@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
> self.exists = False
>
>
> -class DMRaidArrayDevice(DMDevice):
> +class DMRaidArrayDevice(DiskDevice):
> """ A dmraid (device-mapper RAID) device """
> _type = "dm-raid array"
> _packages = ["dmraid"]
> + devDir = "/dev/mapper"
>
> - def __init__(self, name, format=None, size=None,
> - exists=None, parents=None, sysfsPath='):
> + def __init__(self, name, raidSet=None, level=None, format=None, size=None,
> + major=None, minor=None, parents=None, sysfsPath='):
> """ Create a DMRaidArrayDevice instance.
>
> Arguments:
>
> - name -- the device name (generally a device node's basename)
> + name -- the dmraid name also the device node's basename
>
> Keyword Arguments:
>
> + raidSet -- the RaidSet object from block
> + level -- the type of dmraid
> parents -- a list of the member devices
> sysfsPath -- sysfs device path
> size -- the device's size
> format -- a DeviceFormat instance
> - exists -- indicates whether this is an existing device
> """
> if isinstance(parents, list):
> for parent in parents:
> if not parent.format or parent.format.type != "dmraidmember":
> raise ValueError("parent devices must contain dmraidmember format")
> - DMDevice.__init__(self, name, format=format, size=size,
> - parents=parents, sysfsPath=sysfsPath,
> - exists=exists)
> + DiskDevice.__init__(self, name, format=format, size=size,
> + major=major, minor=minor,
> + parents=parents, sysfsPath=sysfsPath)
>
> - def probe(self):
> - """ Probe for any missing information about this device.
> + self.formatClass = get_device_format_class("dmraidmember")
> + if not self.formatClass:
> + raise DeviceError("cannot find class for 'dmraidmember'")
>
> - size
> +
> + self._raidSet = raidSet
> + self._level = level
> +
> + @property
> + def raidSet(self):
> + return self._raidSet
> +
> + @raidSet.setter
> + def raidSet(self, val):
> + # If we change self._raidSet, parents list will be invalid.
> + # Don't allow the change.
> + pass

I still think you should just not define this setter -- how is silently
ignoring things better than pointing out the error? This will mask
programming errors.

> diff --git a/storage/devicetree.py b/storage/devicetree.py
> index 3494d5a..a83279d 100644
> --- a/storage/devicetree.py
> +++ b/storage/devicetree.py
> @@ -914,8 +945,38 @@ class DeviceTree(object):
> parents=[device])
> self._addDevice(md_array)
> elif format.type == "dmraidmember":
> - # look up or create the dmraid array
> - pass
> + major = udev_device_get_major(info)
> + minor = udev_device_get_minor(info)
> + # Have we already created the DMRaidArrayDevice?
> + rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
> + major=major, minor=minor)
> + if rs is None:
> + # FIXME: Should handle not finding a dmriad dev better
> + pass

Shouldn't this be 'return'?

> diff --git a/storage/udev.py b/storage/udev.py
> index 6df00c8..a39b98c 100644
> --- a/storage/udev.py
> +++ b/storage/udev.py
> @@ -270,4 +270,37 @@ def udev_device_get_lv_sizes(info):
>
> return [float(s) / 1024 for s in sizes]
>
> +def udev_device_is_dmraid(info):
> + # Note that this function does *not* identify raid sets.
> + # Tests to see if device is parto of a dmraid set.
> + # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a
> + # string that describes the type of dmraid (isw_raid_member...), I don't
> + # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
> + # dmraid will be everything that is raid and not linux_raid_member
> + if info.has_key("ID_FS_USAGE") and info.has_key("ID_FS_TYPE") and
> + info["ID_FS_USAGE"] == "raid" and
> + info["ID_FS_TYPE"] != "linux_raid_member":
> + return True

As I said before, this will identify LVM PVs as dmraid devices. This has
to be fixed.


_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 04:12 PM
Joel Granados
 
Default Add dmraid functionality to new storage code.

On Fri, Mar 06, 2009 at 05:23:21PM +0100, Hans de Goede wrote:
>
>
> Joel Granados Moreno wrote:
>
> <huge snip>
>
> > diff --git a/storage/__init__.py b/storage/__init__.py
> > index 7bac367..6c241c2 100644
> > --- a/storage/__init__.py
> > +++ b/storage/__init__.py
> > @@ -238,7 +238,11 @@ class Storage(object):
> > does not necessarily reflect the actual on-disk state of the
> > system's disks.
> > """
> > - disks = self.devicetree.getDevicesByType("disk")
> > + disks = []
> > + devices = self.devicetree.devices
> > + for d in devices:
> > + if isinstance(devices[d], DiskDevice):
> > + disks.append(devices[d])
> > disks.sort(key=lambda d: d.name)
> > return disks
> >
> > @@ -250,7 +254,11 @@ class Storage(object):
> > does not necessarily reflect the actual on-disk state of the
> > system's disks.
> > """
> > - partitions = self.devicetree.getDevicesByType("partition")
> > + partitions = []
> > + devices = self.devicetree.devices
> > + for d in devices:
> > + if isinstance(devices[d], PartitionDevice):
> > + partitions.append(devices[d])
> > partitions.sort(key=lambda d: d.name)
> > return partitions
> >
>
> We could use the new devicetree.getDevicesByInstance you add in this same patch here instead.
yep. I could
>
> <more snip>
>
>> @@ -1059,12 +1127,27 @@ class PartitionDevice(StorageDevice):
>> return disk
>> def _setDisk(self, disk):
>> + """Change the parent.
>> +
>> + Setting up a disk is not trivial. It has the potential to change
>> + the underlying object. If necessary we must also change this object.
>> + """
>> log_method_call(self, self.name, old=self.disk, new=disk)
>> if self.disk:
>> self.disk.removeChild()
>> self.parents = [disk]
>> disk.addChild()
>> + if isinstance(disk, DMRaidArrayDevice):
>> + # modify the partition so it can look like the DMRaidPartitionDevice.
>> +
>> + self._type = "dmraid partition"
>> + self._packages = ["dmraid"]
>> + self.devDir = "/dev/mapper"
>> + self.updateSysfsPath = DMDevice.updateSysfsPath
>> + self.getDMNode = DMDevice.getDMNode
>> +
>> +
>> disk = property(lambda p: p._getDisk(), lambda p,d:
>> p._setDisk(d))
>>
>
>
> What if we go the other way around so from being a partition on a DMRaidArrayDevice
> to one on a regular DiskDevice ?
>
>> @@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
>> self.exists = False
>> -class DMRaidArrayDevice(DMDevice):
>> +class DMRaidArrayDevice(DiskDevice):
>> """ A dmraid (device-mapper RAID) device """
>> _type = "dm-raid array"
>> _packages = ["dmraid"]
>> + devDir = "/dev/mapper"
>> - def __init__(self, name, format=None, size=None,
>> - exists=None, parents=None, sysfsPath='):
>> + def __init__(self, name, raidSet=None, level=None, format=None, size=None,
>> + major=None, minor=None, parents=None, sysfsPath='):
>> """ Create a DMRaidArrayDevice instance.
>> Arguments:
>> - name -- the device name (generally a device node's
>> basename)
>> + name -- the dmraid name also the device node's basename
>> Keyword Arguments:
>> + raidSet -- the RaidSet object from block
>> + level -- the type of dmraid
>> parents -- a list of the member devices
>> sysfsPath -- sysfs device path
>> size -- the device's size
>> format -- a DeviceFormat instance
>> - exists -- indicates whether this is an existing device
>> """
>> if isinstance(parents, list):
>> for parent in parents:
>> if not parent.format or parent.format.type != "dmraidmember":
>> raise ValueError("parent devices must contain dmraidmember format")
>> - DMDevice.__init__(self, name, format=format, size=size,
>> - parents=parents, sysfsPath=sysfsPath,
>> - exists=exists)
>> + DiskDevice.__init__(self, name, format=format, size=size,
>> + major=major, minor=minor,
>> + parents=parents, sysfsPath=sysfsPath)
>> - def probe(self):
>> - """ Probe for any missing information about this device.
>> + self.formatClass = get_device_format_class("dmraidmember")
>> + if not self.formatClass:
>> + raise DeviceError("cannot find class for 'dmraidmember'")
>> - size
>> +
>> + self._raidSet = raidSet
>> + self._level = level
>> +
>> + @property
>> + def raidSet(self):
>> + return self._raidSet
>> +
>> + @raidSet.setter
>> + def raidSet(self, val):
>> + # If we change self._raidSet, parents list will be invalid.
>> + # Don't allow the change.
>> + pass
>> +
>
> I think you should just omit the setter then, this will cause python to throw an error
> rather then to ignore the write silently. I think dlehman made a similar remark to an
> earlier version of this patch.
>
> <huge snip>
>
> Regards,
>
> Hans

Yes you are correct. but the comment got lost in all the confustion
will adjust
>
> _______________________________________________
> Anaconda-devel-list mailing list
> Anaconda-devel-list@redhat.com
> https://www.redhat.com/mailman/listinfo/anaconda-devel-list

--
Joel Andres Granados
Brno, Czech Republic, Red Hat.

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 04:18 PM
Joel Granados
 
Default Add dmraid functionality to new storage code.

On Fri, Mar 06, 2009 at 10:38:26AM -0600, David Lehman wrote:
>
> Overall it is good, but there are a couple of things you need to fix.
> See below.
>
> > diff --git a/storage/devices.py b/storage/devices.py
> > index 84cfe1b..dd5a4f1 100644
> > --- a/storage/devices.py
> > +++ b/storage/devices.py
> > @@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
> > self.exists = False
> >
> >
> > -class DMRaidArrayDevice(DMDevice):
> > +class DMRaidArrayDevice(DiskDevice):
> > """ A dmraid (device-mapper RAID) device """
> > _type = "dm-raid array"
> > _packages = ["dmraid"]
> > + devDir = "/dev/mapper"
> >
> > - def __init__(self, name, format=None, size=None,
> > - exists=None, parents=None, sysfsPath='):
> > + def __init__(self, name, raidSet=None, level=None, format=None, size=None,
> > + major=None, minor=None, parents=None, sysfsPath='):
> > """ Create a DMRaidArrayDevice instance.
> >
> > Arguments:
> >
> > - name -- the device name (generally a device node's basename)
> > + name -- the dmraid name also the device node's basename
> >
> > Keyword Arguments:
> >
> > + raidSet -- the RaidSet object from block
> > + level -- the type of dmraid
> > parents -- a list of the member devices
> > sysfsPath -- sysfs device path
> > size -- the device's size
> > format -- a DeviceFormat instance
> > - exists -- indicates whether this is an existing device
> > """
> > if isinstance(parents, list):
> > for parent in parents:
> > if not parent.format or parent.format.type != "dmraidmember":
> > raise ValueError("parent devices must contain dmraidmember format")
> > - DMDevice.__init__(self, name, format=format, size=size,
> > - parents=parents, sysfsPath=sysfsPath,
> > - exists=exists)
> > + DiskDevice.__init__(self, name, format=format, size=size,
> > + major=major, minor=minor,
> > + parents=parents, sysfsPath=sysfsPath)
> >
> > - def probe(self):
> > - """ Probe for any missing information about this device.
> > + self.formatClass = get_device_format_class("dmraidmember")
> > + if not self.formatClass:
> > + raise DeviceError("cannot find class for 'dmraidmember'")
> >
> > - size
> > +
> > + self._raidSet = raidSet
> > + self._level = level
> > +
> > + @property
> > + def raidSet(self):
> > + return self._raidSet
> > +
> > + @raidSet.setter
> > + def raidSet(self, val):
> > + # If we change self._raidSet, parents list will be invalid.
> > + # Don't allow the change.
> > + pass
>
> I still think you should just not define this setter -- how is silently
> ignoring things better than pointing out the error? This will mask
> programming errors.

I blame my brain that did not cope with all the action will change.
>
> > diff --git a/storage/devicetree.py b/storage/devicetree.py
> > index 3494d5a..a83279d 100644
> > --- a/storage/devicetree.py
> > +++ b/storage/devicetree.py
> > @@ -914,8 +945,38 @@ class DeviceTree(object):
> > parents=[device])
> > self._addDevice(md_array)
> > elif format.type == "dmraidmember":
> > - # look up or create the dmraid array
> > - pass
> > + major = udev_device_get_major(info)
> > + minor = udev_device_get_minor(info)
> > + # Have we already created the DMRaidArrayDevice?
> > + rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
> > + major=major, minor=minor)
> > + if rs is None:
> > + # FIXME: Should handle not finding a dmriad dev better
> > + pass
>
> Shouldn't this be 'return'?

This means that something very strange is going on. because we found a
dmraid device and we cannot find the dmraidArray that it relates to.
Just returning seems odd because the installation would continue without
any further action. Guess the best thing to do here is to ignore the
device and continue.
>
> > diff --git a/storage/udev.py b/storage/udev.py
> > index 6df00c8..a39b98c 100644
> > --- a/storage/udev.py
> > +++ b/storage/udev.py
> > @@ -270,4 +270,37 @@ def udev_device_get_lv_sizes(info):
> >
> > return [float(s) / 1024 for s in sizes]
> >
> > +def udev_device_is_dmraid(info):
> > + # Note that this function does *not* identify raid sets.
> > + # Tests to see if device is parto of a dmraid set.
> > + # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a
> > + # string that describes the type of dmraid (isw_raid_member...), I don't
> > + # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
> > + # dmraid will be everything that is raid and not linux_raid_member
> > + if info.has_key("ID_FS_USAGE") and info.has_key("ID_FS_TYPE") and
> > + info["ID_FS_USAGE"] == "raid" and
> > + info["ID_FS_TYPE"] != "linux_raid_member":
> > + return True
>
> As I said before, this will identify LVM PVs as dmraid devices. This has
> to be fixed.

ok, will use the list and will compare that to the list that the
DMRaidArrayDevice class has. For now, it will be the solution.

Another patch in a bit

>
>
> _______________________________________________
> Anaconda-devel-list mailing list
> Anaconda-devel-list@redhat.com
> https://www.redhat.com/mailman/listinfo/anaconda-devel-list

--
Joel Andres Granados
Brno, Czech Republic, Red Hat.

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 04:21 PM
Hans de Goede
 
Default Add dmraid functionality to new storage code.

David Lehman wrote:

Overall it is good, but there are a couple of things you need to fix.
See below.


diff --git a/storage/devices.py b/storage/devices.py
index 84cfe1b..dd5a4f1 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
self.exists = False



-class DMRaidArrayDevice(DMDevice):
+class DMRaidArrayDevice(DiskDevice):
""" A dmraid (device-mapper RAID) device """
_type = "dm-raid array"
_packages = ["dmraid"]
+ devDir = "/dev/mapper"

- def __init__(self, name, format=None, size=None,

- exists=None, parents=None, sysfsPath='):
+ def __init__(self, name, raidSet=None, level=None, format=None, size=None,
+ major=None, minor=None, parents=None, sysfsPath='):
""" Create a DMRaidArrayDevice instance.

Arguments:

- name -- the device name (generally a device node's basename)

+ name -- the dmraid name also the device node's basename

Keyword Arguments:

+ raidSet -- the RaidSet object from block

+ level -- the type of dmraid
parents -- a list of the member devices
sysfsPath -- sysfs device path
size -- the device's size
format -- a DeviceFormat instance
- exists -- indicates whether this is an existing device
"""
if isinstance(parents, list):
for parent in parents:
if not parent.format or parent.format.type != "dmraidmember":
raise ValueError("parent devices must contain dmraidmember format")
- DMDevice.__init__(self, name, format=format, size=size,
- parents=parents, sysfsPath=sysfsPath,
- exists=exists)
+ DiskDevice.__init__(self, name, format=format, size=size,
+ major=major, minor=minor,
+ parents=parents, sysfsPath=sysfsPath)

- def probe(self):

- """ Probe for any missing information about this device.
+ self.formatClass = get_device_format_class("dmraidmember")
+ if not self.formatClass:
+ raise DeviceError("cannot find class for 'dmraidmember'")

- size

+
+ self._raidSet = raidSet
+ self._level = level
+
+ @property
+ def raidSet(self):
+ return self._raidSet
+
+ @raidSet.setter
+ def raidSet(self, val):
+ # If we change self._raidSet, parents list will be invalid.
+ # Don't allow the change.
+ pass


I still think you should just not define this setter -- how is silently
ignoring things better than pointing out the error? This will mask
programming errors.



Ack.


diff --git a/storage/devicetree.py b/storage/devicetree.py
index 3494d5a..a83279d 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -914,8 +945,38 @@ class DeviceTree(object):
parents=[device])
self._addDevice(md_array)
elif format.type == "dmraidmember":
- # look up or create the dmraid array
- pass
+ major = udev_device_get_major(info)
+ minor = udev_device_get_minor(info)
+ # Have we already created the DMRaidArrayDevice?
+ rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
+ major=major, minor=minor)
+ if rs is None:
+ # FIXME: Should handle not finding a dmriad dev better
+ pass


Shouldn't this be 'return'?



Ack.


diff --git a/storage/udev.py b/storage/udev.py
index 6df00c8..a39b98c 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -270,4 +270,37 @@ def udev_device_get_lv_sizes(info):

return [float(s) / 1024 for s in sizes]

+def udev_device_is_dmraid(info):

+ # Note that this function does *not* identify raid sets.
+ # Tests to see if device is parto of a dmraid set.
+ # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a
+ # string that describes the type of dmraid (isw_raid_member...), I don't
+ # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
+ # dmraid will be everything that is raid and not linux_raid_member
+ if info.has_key("ID_FS_USAGE") and info.has_key("ID_FS_TYPE") and
+ info["ID_FS_USAGE"] == "raid" and
+ info["ID_FS_TYPE"] != "linux_raid_member":
+ return True


As I said before, this will identify LVM PVs as dmraid devices. This has
to be fixed.



Weird, I had that fixed, that somehow seems to have gone missing from the patch.
I've attached the patch fixing this.

Regards,

Hans







_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
>From 5f3f06aa5bc8d0386de33ec67d6fc2b1acd4f7a7 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 2 Mar 2009 10:50:34 +0100
Subject: [PATCH 8/9] Do not identify LVM2 PV's as dmraid

We need to fix this better, but this works for now.
---
storage/udev.py | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/storage/udev.py b/storage/udev.py
index d9fff4d..354bd97 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -278,13 +278,16 @@ def udev_device_get_lv_sizes(info):
def udev_device_is_dmraid(info):
# Note that this function does *not* identify raid sets.
# Tests to see if device is parto of a dmraid set.
- # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a
+ # dmraid and mdraid and lvm have the same ID_FS_USAGE string
+ # ID_FS_TYPE has a
# string that describes the type of dmraid (isw_raid_member...), I don't
# want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
# dmraid will be everything that is raid and not linux_raid_member
+ # and not LVM
if info.has_key("ID_FS_USAGE") and info.has_key("ID_FS_TYPE") and
info["ID_FS_USAGE"] == "raid" and
- info["ID_FS_TYPE"] != "linux_raid_member":
+ info["ID_FS_TYPE"] != "linux_raid_member" and
+ info["ID_FS_TYPE"] != "LVM2_member":
return True

return False
--
1.6.1.3

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 04:27 PM
David Lehman
 
Default Add dmraid functionality to new storage code.

> > > + # Have we already created the DMRaidArrayDevice?
> > > + rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
> > > + major=major, minor=minor)
> > > + if rs is None:
> > > + # FIXME: Should handle not finding a dmriad dev better
> > > + pass
> >
> > Shouldn't this be 'return'?
>
> This means that something very strange is going on. because we found a
> dmraid device and we cannot find the dmraidArray that it relates to.
> Just returning seems odd because the installation would continue without
> any further action. Guess the best thing to do here is to ignore the
> device and continue.

Right. My only concern is that the next line makes a method call with
rs.name (or similar) as an argument, which will obviously cause a
failure if rs is None. I'd suggest to log it and then do whatever you
want as long as it doesn't cause a traceback :-)

Dave

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 
Old 03-06-2009, 04:50 PM
Joel Granados Moreno
 
Default Add dmraid functionality to new storage code.

* storage/devices.py (DMRaidArrayDevice): Complete the DMRaidArrayDevice
class.
* storage/devices.py (PartitionDeviceFactory): When creating a
partition we need to decide, based on the device holding the
partition, what type of partition class will be returned.
* storage/devices.py (PartitionDevice): When setting the disk we must be
careful to change stuff accordingly.

* storage/devicetree.py (addUdevDevice): Handle the creation of the
dmraid device and its members in the addUdeveDevice function.

* storage/formats/dmraid.py (DMRaidMember): Complete the format that
handles devices being members of a dmraid array.
* storage/udev.py (udev_device_is_dmraid): add a function that
recognizes dmraid devices from the provided info list.

* storage/udev.py (udev_device_get_dmraid_partition_disk): function that
gets the disk string from partition info.
* storage/udev.py (udev_device_is_dmraid_partition): function that
checks for dmraid partitions.

* storage/__init__.py (disks(self)): return a list of disks from the
internal attribute.
* storage/__init__.py (Storage.disks): we really want to make sure we
return all the objects that comply with the DiskDevice interface
(inheret from DiskDevice)
* storage/__init__.py (Storage.partitions): Same as above but for
PartitionDevice.

* iw/autopart_type (PartitionTypeWindow(InstallWindow)): use disk.name
instead of munging the first 5 characters of the path.

* storage/partitioning (newPartition): Use the new partition factory to
create a partition.
---
iw/autopart_type.py | 9 +--
iw/partition_gui.py | 8 +-
storage/__init__.py | 22 ++++-
storage/devices.py | 202 +++++++++++++++++++++++++++++++++++++++++----
storage/devicetree.py | 92 +++++++++++++++++---
storage/formats/dmraid.py | 23 ++++--
storage/partitioning.py | 4 +-
storage/udev.py | 33 ++++++++
8 files changed, 341 insertions(+), 52 deletions(-)

diff --git a/iw/autopart_type.py b/iw/autopart_type.py
index ba8c0dc..700d7da 100644
--- a/iw/autopart_type.py
+++ b/iw/autopart_type.py
@@ -381,14 +381,11 @@ class PartitionTypeWindow(InstallWindow):
else:
defaultBoot = None
for disk in self.storage.disks:
- partedDisk = disk.partedDisk
- if partedDisk.device.path[5:] not in self.anaconda.id.bootloader.drivelist:
+ if disk.name not in self.anaconda.id.bootloader.drivelist:
continue
- size = partedDisk.device.getSize(unit="MB")
- dispstr = "%s %8.0f MB %s" %(partedDisk.device.path[5:],
- size, partedDisk.device.model)
+ dispstr = "%s %8.0f MB %s" %(disk.name, disk.size, disk.partedDisk.device.model)
i = bootstore.append(None)
- bootstore[i] = (dispstr, partedDisk.device.path[5:])
+ bootstore[i] = (dispstr, disk.name)
if disk.name == defaultBoot:
self.bootcombo.set_active_iter(i)

diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index c704b08..9dae436 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py
@@ -142,12 +142,12 @@ class DiskStripeSlice:
if self.partition.type & parted.PARTITION_FREESPACE:
rc = "Free
"
else:
- rc = "%s
" % (self.partition.getDeviceNodeName(),)
+ rc = "%s
" % (self.partition.getDeviceNodeName().split("/")[-1],)
rc = rc + "%Ld MB" % (self.partition.getSize(unit="MB"),)
return rc

def getDeviceName(self):
- return self.partition.getDeviceNodeName()
+ return self.partition.getDeviceNodeName().split("/")[-1]

def update(self):
disk = self.parent.getDisk()
@@ -808,7 +808,7 @@ class PartitionWindow(InstallWindow):
part = part.nextPartition()
continue

- partName = part.getDeviceNodeName()
+ partName = part.getDeviceNodeName().split("/")[-1]
device = self.storage.devicetree.getDeviceByName(partName)
if not device and not part.type & parted.PARTITION_FREESPACE:
raise RuntimeError("can't find partition %s in device"
@@ -1054,7 +1054,7 @@ class PartitionWindow(InstallWindow):
self.editLVMVolumeGroup(device)
elif device.type == "lvmlv":
self.editLVMVolumeGroup(device)
- elif device.type == "partition":
+ elif isinstance(device, storage.devices.PartitionDevice):
self.editPartition(device)

# isNew implies that this request has never been successfully used before
diff --git a/storage/__init__.py b/storage/__init__.py
index 7bac367..6c241c2 100644
--- a/storage/__init__.py
+++ b/storage/__init__.py
@@ -238,7 +238,11 @@ class Storage(object):
does not necessarily reflect the actual on-disk state of the
system's disks.
"""
- disks = self.devicetree.getDevicesByType("disk")
+ disks = []
+ devices = self.devicetree.devices
+ for d in devices:
+ if isinstance(devices[d], DiskDevice):
+ disks.append(devices[d])
disks.sort(key=lambda d: d.name)
return disks

@@ -250,7 +254,11 @@ class Storage(object):
does not necessarily reflect the actual on-disk state of the
system's disks.
"""
- partitions = self.devicetree.getDevicesByType("partition")
+ partitions = []
+ devices = self.devicetree.devices
+ for d in devices:
+ if isinstance(devices[d], PartitionDevice):
+ partitions.append(devices[d])
partitions.sort(key=lambda d: d.name)
return partitions

@@ -423,7 +431,7 @@ class Storage(object):
if device.name in self.protectedPartitions:
return _("This partition is holding the data for the hard "
"drive install.")
- elif device.type == "partition" and device.isProtected:
+ elif isinstance(device, PartitionDevice) and device.isProtected:
# LDL formatted DASDs always have one partition, you'd have to
# reformat the DASD in CDL mode to get rid of it
return _("You cannot delete a partition of a LDL formatted "
@@ -445,7 +453,7 @@ class Storage(object):
else:
return _("This device is part of a LVM volume "
"group.")
- elif device.type == "partition" and device.isExtended:
+ elif isinstance(device, PartitionDevice) and device.isExtended:
reasons = {}
for dep in self.deviceDeps(device):
reason = self.deviceImmutable(dep)
@@ -473,13 +481,17 @@ class Storage(object):

if kwargs.has_key("disks"):
parents = kwargs.pop("disks")
+ if isinstance(parents, Device):
+ kwargs["parents"] = [parents]
+ else:
+ kwargs["parents"] = parents

if kwargs.has_key("name"):
name = kwargs.pop("name")
else:
name = "req%d" % self.nextID

- return PartitionDevice(name, *args, **kwargs)
+ return PartitionDeviceFactory(name, *args, **kwargs)

def newMDArray(self, *args, **kwargs):
""" Return a new MDRaidArrayDevice instance for configuring. """
diff --git a/storage/devices.py b/storage/devices.py
index 84cfe1b..dd5a4f1 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -127,6 +127,74 @@ def get_device_majors():
return majors
device_majors = get_device_majors()

+def PartitionDeviceFactory(*args, **kwargs):
+ """This will decide what PartitionDevice class will be used.
+
+ Arguments:
+
+ name -- the device name (generally a device node's basename)
+
+ Keyword Arguments:
+
+ exists -- indicates whether this is an existing device
+ format -- the device's format (DeviceFormat instance)
+
+ For existing partitions:
+
+ parents -- the disk that contains this partition
+ major -- the device major
+ minor -- the device minor
+ sysfsPath -- sysfs device path
+
+ For new partitions:
+
+ partType -- primary,extended,&c (as parted constant)
+ grow -- whether or not to grow the partition
+ maxsize -- max size for growable partitions (in MB)
+ size -- the device's size (in MB)
+ bootable -- whether the partition is bootable
+ parents -- a list of potential containing disks
+
+ The decision will be made base on finding the disk by name
+ """
+ # FIXME: PRePBootDevice should be here somehow.!!!
+ roots = ["/dev", "/dev/mapper"]
+ # firs lets normalize the name
+ norm_name = args[0].split("/")[-1]
+
+ # We look for the disk in /dev. From PartitionDevice its the [0] one.
+ if (not kwargs.has_key("parents")) or
+ (kwargs.has_key("exists") and not kwargs["exists"]):
+ # Cant really choose a good type of class, default to PartitionDevice
+ # This will be considered as a request.
+ return PartitionDevice(*args, **kwargs)
+ else:
+ parents = kwargs["parents"]
+ if isinstance(parents, Device):
+ parents = [parents]
+ # we receive a list of parents. look for the disk that contains the name
+ # if we dont find the name we will return PartitionDevice and let it raise
+ # the exception.
+ for root in roots:
+ for parent in parents:
+ path = os.path.join(root,norm_name)
+ log.debug("looking up parted Partition: %s" % path)
+ part = parent.partedDisk.getPartitionByPath(path)
+ if not part:
+ continue
+ else:
+ # we have found a part. no make the decision based on path
+ if path.startswith(roots[1]):
+ #we create a DMPartition
+ return DMRaidPartitionDevice(*args, **kwargs)
+ elif path.startswith(roots[0]):
+ # make sure that the parent is consistent
+ kwargs["parents"] = [parent]
+ return PartitionDevice(*args, **kwargs)
+
+ # If we get here, we did not find anything.
+ return PartitionDevice(*args, **kwargs)
+
class Device(object):
""" A generic device.

@@ -861,14 +929,14 @@ class PartitionDevice(StorageDevice):
# no need to clobber our name
else:
self._partedPartition = partition
- self._name = partition.getDeviceNodeName()
+ self._name = partition.getDeviceNodeName().split("/")[-1]

partedPartition = property(lambda d: d._getPartedPartition(),
lambda d,p: d._setPartedPartition(p))

def dependsOn(self, dep):
""" Return True if this device depends on dep. """
- if dep.type == "partition" and dep.isExtended and self.isLogical:
+ if isinstance(dep, PartitionDevice) and dep.isExtended and self.isLogical:
return True

return Device.dependsOn(self, dep)
@@ -1051,7 +1119,7 @@ class PartitionDevice(StorageDevice):
geometry.length = new_length

def _getDisk(self):
- """ The disk that contains this partition. """
+ """ The disk that contains this partition."""
try:
disk = self.parents[0]
except IndexError:
@@ -1059,12 +1127,27 @@ class PartitionDevice(StorageDevice):
return disk

def _setDisk(self, disk):
+ """Change the parent.
+
+ Setting up a disk is not trivial. It has the potential to change
+ the underlying object. If necessary we must also change this object.
+ """
log_method_call(self, self.name, old=self.disk, new=disk)
if self.disk:
self.disk.removeChild()

self.parents = [disk]
disk.addChild()
+ if isinstance(disk, DMRaidArrayDevice):
+ # modify the partition so it can look like the DMRaidPartitionDevice.
+
+ self._type = "dmraid partition"
+ self._packages = ["dmraid"]
+ self.devDir = "/dev/mapper"
+ self.updateSysfsPath = DMDevice.updateSysfsPath
+ self.getDMNode = DMDevice.getDMNode
+
+

disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))

@@ -2069,41 +2152,130 @@ class MDRaidArrayDevice(StorageDevice):
self.exists = False


-class DMRaidArrayDevice(DMDevice):
+class DMRaidArrayDevice(DiskDevice):
""" A dmraid (device-mapper RAID) device """
_type = "dm-raid array"
_packages = ["dmraid"]
+ devDir = "/dev/mapper"

- def __init__(self, name, format=None, size=None,
- exists=None, parents=None, sysfsPath='):
+ def __init__(self, name, raidSet=None, level=None, format=None, size=None,
+ major=None, minor=None, parents=None, sysfsPath='):
""" Create a DMRaidArrayDevice instance.

Arguments:

- name -- the device name (generally a device node's basename)
+ name -- the dmraid name also the device node's basename

Keyword Arguments:

+ raidSet -- the RaidSet object from block
+ level -- the type of dmraid
parents -- a list of the member devices
sysfsPath -- sysfs device path
size -- the device's size
format -- a DeviceFormat instance
- exists -- indicates whether this is an existing device
"""
if isinstance(parents, list):
for parent in parents:
if not parent.format or parent.format.type != "dmraidmember":
raise ValueError("parent devices must contain dmraidmember format")
- DMDevice.__init__(self, name, format=format, size=size,
- parents=parents, sysfsPath=sysfsPath,
- exists=exists)
+ DiskDevice.__init__(self, name, format=format, size=size,
+ major=major, minor=minor,
+ parents=parents, sysfsPath=sysfsPath)

- def probe(self):
- """ Probe for any missing information about this device.
+ self.formatClass = get_device_format_class("dmraidmember")
+ if not self.formatClass:
+ raise DeviceError("cannot find class for 'dmraidmember'")

- size
+
+ self._raidSet = raidSet
+ self._level = level
+
+ @property
+ def raidSet(self):
+ return self._raidSet
+
+ @raidSet.setter
+ def raidSet(self, val):
+ # If we change self._raidSet, parents list will be invalid.
+ # Don't allow the change.
+ pass
+
+ def _addDevice(self, device):
+ """ Add a new member device to the array.
+
+ XXX This is for use when probing devices, not for modification
+ of arrays.
"""
- raise NotImplementedError("probe method not defined for DMRaidArrayDevice")
+ log_method_call(self, self.name, device=device.name, status=self.status)
+
+ if not self.exists:
+ raise DeviceError("device has not been created")
+
+ if not isinstance(device.format, self.formatClass):
+ raise ValueError("invalid device format for dmraid member")
+
+ if device in self.members:
+ raise ValueError("device is already a member of this array")
+
+ # we added it, so now set up the relations
+ self.devices.append(device)
+ device.addChild()
+
+ @property
+ def members(self):
+ return self.parents
+
+ @property
+ def devices(self):
+ """ Return a list of this array's member device instances. """
+ return self.parents
+
+ def activate(self, mknod=True):
+ self._raidSet.activate(mknod=mknod)
+
+ def deactivate(self):
+ self._raidSet.deactivate()
+
+ # We are more like a disk then a dmdevice, but we are still a dmdevice,
+ # so we need to "inherit" some functions from dmdevice
+ def updateSysfsPath(self):
+ DMDevice.updateSysfsPath(self)
+
+ def getDMNode(self):
+ DMDevice.getDMNode(self)
+
+ def teardown(self, recursive=None):
+ # avoid DiskDevice's overriding of teardown()
+ StorageDevice.teardown(self, recursive)
+
+
+class DMRaidPartitionDevice(PartitionDevice):
+ """ A disk partition in a dmraid array, identical to a general
+ PartitionDevice, except for the device path and sysfs path
+ """
+ _type = "dmraid partition"
+ _packages = ["dmraid"]
+ devDir = "/dev/mapper"
+
+ def __init__(self, name, format=None,
+ size=None, grow=False, maxsize=None,
+ major=None, minor=None, bootable=None,
+ sysfsPath=', parents=None, exists=None,
+ partType=None, primary=False):
+ PartitionDevice.__init__(self, name, format=format, size=size,
+ major=major, minor=minor, bootable=bootable,
+ sysfsPath=sysfsPath, parents=parents,
+ exists=exists, partType=partType,
+ primary=primary)
+
+ # We are more like a partition then a dmdevice, but we are still a dmdevice
+ # so we need to "inherit" some functions from dmdevice
+ def updateSysfsPath(self):
+ DMDevice.updateSysfsPath(self)
+
+ def getDMNode(self):
+ DMDevice.getDMNode(self)


class MultipathDevice(DMDevice):
diff --git a/storage/devicetree.py b/storage/devicetree.py
index 3494d5a..a83279d 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -21,6 +21,7 @@
#

import os
+import block

from errors import *
from devices import *
@@ -458,7 +459,7 @@ class DeviceTree(object):
raise ValueError("Cannot remove non-leaf device '%s'" % dev.name)

# if this is a partition we need to remove it from the parted.Disk
- if dev.type == "partition":
+ if isinstance(dev, PartitionDevice):
dev.disk.removePartition(dev)

self._devices.remove(dev)
@@ -558,9 +559,9 @@ class DeviceTree(object):
# special handling for extended partitions since the logical
# partitions and their deps effectively depend on the extended
logicals = []
- if dep.type == "partition" and dep.isExtended:
+ if isinstance(dep, PartitionDevice):
# collect all of the logicals on the same disk
- for part in self.getDevicesByType("partition"):
+ for part in self.getDevicesByInstance(PartitionDevice):
if part.isLogical and part.disk == dep.disk:
logicals.append(part)

@@ -601,6 +602,13 @@ class DeviceTree(object):
# this is a partition on a disk in the ignore list
return True

+ # Ignore partitions found on the raw disks which are part of a
+ # dmraidset
+ for set in self.getDevicesByType("dm-raid array"):
+ for disk in set.parents:
+ if disk.name == os.path.basename(os.path.dirname(sysfs_path)):
+ return True
+
# FIXME: check for virtual devices whose slaves are on the ignore list

def addUdevDevice(self, info):
@@ -667,6 +675,19 @@ class DeviceTree(object):
log.error("failure scanning device %s" % name)
return

+ if device is None and
+ udev_device_is_dmraid_partition(info, self):
+ diskname = udev_device_get_dmraid_partition_disk(info)
+ disk = self.getDeviceByName(diskname)
+ device = PartitionDeviceFactory(name,
+ sysfsPath=sysfs_path,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ exists=True,
+ parents=[disk])
+ self._addDevice(device)
+ #self.ignoredDisks.append(name)
+
# if we get here, we found all of the slave devices and
# something must be wrong -- if all of the slaves are in
# the tree, this device should be as well
@@ -741,6 +762,17 @@ class DeviceTree(object):
minor=udev_device_get_minor(info),
sysfsPath=sysfs_path)
self._addDevice(device)
+ elif udev_device_is_dmraid(info):
+ # This is just temporary as I need to differentiate between the
+ # device that has partitions and device that dont.
+ log.debug("%s is part of a dmraid" % name)
+ device = self.getDeviceByName(name)
+ if device is None:
+ device = StorageDevice(name,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ sysfsPath=sysfs_path, exists=True)
+ self._addDevice(device)
elif udev_device_is_disk(info):
log.debug("%s is a disk" % name)
device = self.getDeviceByName(name)
@@ -793,12 +825,12 @@ class DeviceTree(object):
log.error("failure scanning device %s" % disk_name)
return

- device = PartitionDevice(name,
- sysfsPath=sysfs_path,
- major=udev_device_get_major(info),
- minor=udev_device_get_minor(info),
- exists=True,
- parents=[disk])
+ device = PartitionDeviceFactory(name,
+ sysfsPath=sysfs_path,
+ major=udev_device_get_major(info),
+ minor=udev_device_get_minor(info),
+ exists=True,
+ parents=[disk])
self._addDevice(device)

#
@@ -824,9 +856,8 @@ class DeviceTree(object):
except KeyError:
log.debug("mdraid member %s has no md uuid" % name)
elif format_type == "isw_raid_member":
- # dmraid
- # TODO: collect name of containing raidset
- # TODO: implement dmraid member format class
+ # We dont add any new args because we intend to use the same
+ # block.RaidSet object for all the related devices.
pass
elif format_type == "LVM2_member":
# lvm
@@ -914,8 +945,38 @@ class DeviceTree(object):
parents=[device])
self._addDevice(md_array)
elif format.type == "dmraidmember":
- # look up or create the dmraid array
- pass
+ major = udev_device_get_major(info)
+ minor = udev_device_get_minor(info)
+ # Have we already created the DMRaidArrayDevice?
+ rs = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
+ major=major, minor=minor)
+ if rs is None:
+ # FIXME: Should handle not finding a dmriad dev better
+ pass
+
+ dm_array = self.getDeviceByName(rs.name)
+ if dm_array is not None:
+ # We add the new device.
+ dm_array._addDevice(device)
+ else:
+ # Activate the Raid set.
+ rs.activate(mknod=True)
+
+ # Create the DMRaidArray
+ dm_array = DMRaidArrayDevice(rs.name,
+ major=major, minor=minor,
+ raidSet=rs,
+ level=rs.level,
+ parents=[device])
+
+ self._addDevice(dm_array)
+
+ # Use the rs's object on the device.
+ # pyblock can return the memebers of a set and the device has
+ # the attribute to hold it. But ATM we are not really using it.
+ # Commenting this out until we really need it.
+ #device.format.raidmem = block.getMemFromRaidSet(dm_array,
+ # major=major, minor=minor, uuid=uuid, name=name)
elif format.type == "lvmpv":
# lookup/create the VG and LVs
try:
@@ -1077,6 +1138,9 @@ class DeviceTree(object):
# TODO: expand this to catch device format types
return [d for d in self._devices if d.type == device_type]

+ def getDevicesByInstance(self, device_class):
+ return [d for d in self._devices if isinstance(d, device_class)]
+
@property
def devices(self):
""" Dict with device path keys and Device values. """
diff --git a/storage/formats/dmraid.py b/storage/formats/dmraid.py
index d458b45..ef80902 100644
--- a/storage/formats/dmraid.py
+++ b/storage/formats/dmraid.py
@@ -20,6 +20,8 @@
# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
#

+import block
+
from iutil import log_method_call
#from dm import dm_node_from_name
from ..errors import *
@@ -65,25 +67,34 @@ class DMRaidMember(DeviceFormat):

device -- path to the underlying device
uuid -- this format's UUID
- raidSet -- the name of the raidset this member belongs to
exists -- indicates whether this is an existing format

+ On initialization this format is like DeviceFormat
+
"""
log_method_call(self, *args, **kwargs)
DeviceFormat.__init__(self, *args, **kwargs)
-
- self.raidSet = kwargs.get("raidSet")
+
+ # Initialize the attribute that will hold the block object.
+ self._raidmem = None
+
+ @property
+ def raidmem(self):
+ return self._raidmem
+
+ @raidmem.setter
+ def raidmem(self, raidmem):
+ self._raidmem = raidmem

def create(self, *args, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- raise DMRaidMemberError("creation of dmraid members is not supported")
+ raise DMRaidMemberError("creation of dmraid members is non-sense")

def destroy(self, *args, **kwargs):
log_method_call(self, device=self.device,
type=self.type, status=self.status)
- raise DMRaidMemberError("destruction of dmraid members is not supported")
-
+ raise DMRaidMemberError("destruction of dmraid members is non-sense")

register_device_format(DMRaidMember)

diff --git a/storage/partitioning.py b/storage/partitioning.py
index d1f2d4d..78929cf 100644
--- a/storage/partitioning.py
+++ b/storage/partitioning.py
@@ -32,7 +32,7 @@ from constants import *

from errors import *
from deviceaction import *
-from devices import PartitionDevice, LUKSDevice
+from devices import PartitionDeviceFactory, LUKSDevice

import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
@@ -530,7 +530,7 @@ def doPartitioning(storage, exclusiveDisks=None):
# that does not exist means leaving self.parents empty and instead
# populating self.req_disks. In this case, we need to skip past
# that since this partition is already defined.
- device = PartitionDevice(extended.getDeviceNodeName(),
+ device = PartitionDeviceFactory(extended.getDeviceNodeName( ),
parents=disk)
device.parents = [disk]
device.partedPartition = extended
diff --git a/storage/udev.py b/storage/udev.py
index 6df00c8..a39b98c 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -270,4 +270,37 @@ def udev_device_get_lv_sizes(info):

return [float(s) / 1024 for s in sizes]

+def udev_device_is_dmraid(info):
+ # Note that this function does *not* identify raid sets.
+ # Tests to see if device is parto of a dmraid set.
+ # dmraid and mdriad have the same ID_FS_USAGE string, ID_FS_TYPE has a
+ # string that describes the type of dmraid (isw_raid_member...), I don't
+ # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
+ # dmraid will be everything that is raid and not linux_raid_member
+ if info.has_key("ID_FS_USAGE") and info.has_key("ID_FS_TYPE") and
+ info["ID_FS_USAGE"] == "raid" and
+ info["ID_FS_TYPE"] != "linux_raid_member":
+ return True
+
+ return False
+
+def udev_device_get_dmraid_partition_disk(info):
+ try:
+ p_index = info["DM_NAME"].rindex("p")
+ except:
+ return None
+
+ if not info["DM_NAME"][p_index+1:].isdigit():
+ return None
+
+ return info["DM_NAME"][_index]
+
+def udev_device_is_dmraid_partition(info, devicetree):
+ diskname = udev_device_get_dmraid_partition_disk(info)
+ dmraid_devices = devicetree.getDevicesByType("dm-raid array")
+
+ for device in dmraid_devices:
+ if diskname == device.name:
+ return True

+ return False
--
1.6.0.6

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@redhat.com
https://www.redhat.com/mailman/listinfo/anaconda-devel-list
 

Thread Tools




All times are GMT. The time now is 05:05 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org