From: David Lehman dlehman@redhat.com
MD firmware RAID has an intermediate layer (the container). RAID level checking and size calculation need to be able to access the list of member devices. --- blivet/devices/btrfs.py | 4 +++ blivet/devices/md.py | 15 ++++------ blivet/devices/raid.py | 6 ++-- tests/devices_test/device_properties_test.py | 42 ++++++++++++++-------------- 4 files changed, 34 insertions(+), 33 deletions(-)
diff --git a/blivet/devices/btrfs.py b/blivet/devices/btrfs.py index f598a4b..02aeb0a 100644 --- a/blivet/devices/btrfs.py +++ b/blivet/devices/btrfs.py @@ -212,6 +212,10 @@ def __init__(self, *args, **kwargs):
self._defaultSubVolumeID = None
+ @property + def members(self): + return list(self.parents) + def _setLevel(self, value, data): """ Sets a valid level for this device and level type.
diff --git a/blivet/devices/md.py b/blivet/devices/md.py index b204e43..6425dd9 100644 --- a/blivet/devices/md.py +++ b/blivet/devices/md.py @@ -224,7 +224,7 @@ def size(self): """ if not self.exists or not self.mediaPresent: try: - size = self.level.get_size([d.size for d in self.devices], + size = self.level.get_size([d.size for d in self.members], self.memberDevices, self.chunkSize, self.getSuperBlockSize) @@ -436,11 +436,6 @@ def complete(self): """ return (self.memberDevices <= len(self.members)) or not self.exists
- @property - def devices(self): - """ Return a list of this array's member device instances. """ - return self.parents - def _postSetup(self): super(MDRaidArrayDevice, self)._postSetup() self.updateSysfsPath() @@ -450,7 +445,7 @@ def _setup(self, orig=False): log_method_call(self, self.name, orig=orig, status=self.status, controllable=self.controllable) disks = [] - for member in self.devices: + for member in self.members: member.setup(orig=orig) disks.append(member.path)
@@ -500,14 +495,14 @@ def _postCreate(self): # XXX this won't work for containers since no UUID is reported for them info = blockdev.md.detail(self.path) self.uuid = info.uuid - for member in self.devices: + for member in self.members: member.format.mdUuid = self.uuid
def _create(self): """ Create the device. """ log_method_call(self, self.name, status=self.status) - disks = [disk.path for disk in self.devices] - spares = len(self.devices) - self.memberDevices + disks = [disk.path for disk in self.members] + spares = len(self.members) - self.memberDevices level = None if self.level: level = str(self.level) diff --git a/blivet/devices/raid.py b/blivet/devices/raid.py index 60fb5a2..85e1ece 100644 --- a/blivet/devices/raid.py +++ b/blivet/devices/raid.py @@ -31,6 +31,8 @@ @add_metaclass(abc.ABCMeta) class RaidDevice(StorageDevice): """ Metaclass for devices that support RAID in some form. """ + members = abc.abstractproperty(lambda s: [], + doc="A list of the member device instances")
def _validateRaidLevel(self, level, parent_diff=0): """ Returns an error message if the RAID level is invalid for this @@ -47,8 +49,8 @@ def _validateRaidLevel(self, level, parent_diff=0): number of parents. The number is positive for added parents, negative for removed parents. """ - num_parents = len(self.parents) + parent_diff - if not self.exists and num_parents < level.min_members: + num_members = len(self.members) + parent_diff # pylint: disable=no-member + if not self.exists and num_members < level.min_members: message = P_( "RAID level %(raidLevel)s requires that device have at least %(minMembers)d member.", "RAID level %(raidLevel)s requires that device have at least %(minMembers)d members.", diff --git a/tests/devices_test/device_properties_test.py b/tests/devices_test/device_properties_test.py index aad60a1..a72f27d 100644 --- a/tests/devices_test/device_properties_test.py +++ b/tests/devices_test/device_properties_test.py @@ -112,12 +112,12 @@ def __init__(self, methodName='runTest'): state_functions = { "createBitmap" : xform(lambda d, a: self.assertFalse), "description" : xform(self.assertIsNotNone), - "devices" : xform(lambda x, m: self.assertEqual(len(x), 0, m) and - self.assertIsInstance(x, ParentList, m)), "formatClass" : xform(self.assertIsNotNone), "level" : xform(self.assertIsNone), "mdadmFormatUUID" : xform(self.assertIsNone), "memberDevices" : xform(lambda x, m: self.assertEqual(x, 0, m)), + "members" : xform(lambda x, m: self.assertEqual(len(x), 0, m) and + self.assertIsInstance(x, list, m)), "metadataVersion" : xform(lambda x, m: self.assertEqual(x, "default", m)), "spares" : xform(lambda x, m: self.assertEqual(x, 0, m)), "totalDevices" : xform(lambda x, m: self.assertEqual(x, 0, m)) @@ -365,35 +365,35 @@ def testMDRaidArrayDeviceInit(self): ## level tests ## self.stateCheck(self.dev1, - devices=xform(lambda x, m: self.assertEqual(len(x), 1, m)), level=xform(lambda x, m: self.assertEqual(x.name, "container", m)), parents=xform(lambda x, m: self.assertEqual(len(x), 1, m)), mediaPresent=xform(self.assertFalse), + members=xform(lambda x, m: self.assertEqual(len(x), 1, m)), type=xform(lambda x, m: self.assertEqual(x, "mdcontainer", m))) self.stateCheck(self.dev2, createBitmap=xform(self.assertFalse), - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), level=xform(lambda x, m: self.assertEqual(x.number, 0, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 2, m))) self.stateCheck(self.dev3, - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), level=xform(lambda x, m: self.assertEqual(x.number, 1, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 2, m))) self.stateCheck(self.dev4, - devices=xform(lambda x, m: self.assertEqual(len(x), 3, m)), level=xform(lambda x, m: self.assertEqual(x.number, 4, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 3, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 3, m))) self.stateCheck(self.dev5, - devices=xform(lambda x, m: self.assertEqual(len(x), 3, m)), level=xform(lambda x, m: self.assertEqual(x.number, 5, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 3, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 3, m))) self.stateCheck(self.dev6, - devices=xform(lambda x, m: self.assertEqual(len(x), 4, m)), level=xform(lambda x, m: self.assertEqual(x.number, 6, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 4, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 4, m))) self.stateCheck(self.dev7, - devices=xform(lambda x, m: self.assertEqual(len(x), 4, m)), level=xform(lambda x, m: self.assertEqual(x.number, 10, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 4, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 4, m)))
## @@ -410,10 +410,10 @@ def testMDRaidArrayDeviceInit(self): ## self.stateCheck(self.dev9, createBitmap=xform(self.assertFalse), - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), isDisk=xform(self.assertTrue), level=xform(lambda x, m: self.assertEqual(x.number, 0, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 2, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), partitionable=xform(self.assertTrue), totalDevices=xform(lambda x, m: self.assertEqual(x, 2, m)), @@ -424,16 +424,16 @@ def testMDRaidArrayDeviceInit(self): ## self.stateCheck(self.dev10, createBitmap=xform(self.assertFalse), - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), level=xform(lambda x, m: self.assertEqual(x.number, 0, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 2, m)), targetSize=xform(lambda x, m: self.assertEqual(x, Size("32 MiB"), m)))
self.stateCheck(self.dev11, - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), isDisk=xform(self.assertTrue), level=xform(lambda x, m: self.assertEqual(x.number, 1, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 2, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), partitionable=xform(self.assertTrue), targetSize=xform(lambda x, m: self.assertEqual(x, Size("32 MiB"), m)), @@ -441,10 +441,10 @@ def testMDRaidArrayDeviceInit(self): type=xform(lambda x, m: self.assertEqual(x, "mdbiosraidarray", m)))
self.stateCheck(self.dev12, - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), isDisk=xform(self.assertTrue), level=xform(lambda x, m: self.assertEqual(x.number, 1, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 2, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), partitionable=xform(self.assertTrue), targetSize=xform(lambda x, m: self.assertEqual(x, Size("32 MiB"), m)), @@ -453,9 +453,9 @@ def testMDRaidArrayDeviceInit(self):
self.stateCheck(self.dev13, createBitmap=xform(self.assertFalse), - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), level=xform(lambda x, m: self.assertEqual(x.number, 0, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 3, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), size=xform(lambda x, m: self.assertEqual(x, Size("3 MiB"), m)), targetSize=xform(lambda x, m: self.assertEqual(x, Size("32 MiB"), m)), @@ -463,60 +463,60 @@ def testMDRaidArrayDeviceInit(self):
self.stateCheck(self.dev14, createBitmap=xform(self.assertTrue), - devices=xform(lambda x, m: self.assertEqual(len(x), 3, m)), level=xform(lambda x, m: self.assertEqual(x.number, 4, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 3, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 3, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), size=xform(lambda x, m: self.assertEqual(x, Size("2 MiB"), m)), totalDevices=xform(lambda x, m: self.assertEqual(x, 3, m)))
self.stateCheck(self.dev15, createBitmap=xform(self.assertTrue), - devices=xform(lambda x, m: self.assertEqual(len(x), 3, m)), level=xform(lambda x, m: self.assertEqual(x.number, 5, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 3, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 3, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), size=xform(lambda x, m: self.assertEqual(x, Size("2 MiB"), m)), totalDevices=xform(lambda x, m: self.assertEqual(x, 3, m)))
self.stateCheck(self.dev16, createBitmap=xform(self.assertTrue), - devices=xform(lambda x, m: self.assertEqual(len(x), 4, m)), level=xform(lambda x, m: self.assertEqual(x.number, 6, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 4, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 4, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), size=xform(lambda x, m: self.assertEqual(x, Size("2 MiB"), m)), totalDevices=xform(lambda x, m: self.assertEqual(x, 4, m)))
self.stateCheck(self.dev17, createBitmap=xform(self.assertTrue), - devices=xform(lambda x, m: self.assertEqual(len(x), 4, m)), level=xform(lambda x, m: self.assertEqual(x.number, 10, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 4, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 4, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), size=xform(lambda x, m: self.assertEqual(x, Size("2 MiB"), m)), totalDevices=xform(lambda x, m: self.assertEqual(x, 4, m)))
self.stateCheck(self.dev18, createBitmap=xform(self.assertTrue), - devices=xform(lambda x, m: self.assertEqual(len(x), 4, m)), level=xform(lambda x, m: self.assertEqual(x.number, 10, m)), memberDevices=xform(lambda x, m: self.assertEqual(x, 4, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 4, m)), parents=xform(lambda x, m: self.assertNotEqual(x, [], m)), size=xform(lambda x, m: self.assertEqual(x, Size("2 MiB"), m)), spares=xform(lambda x, m: self.assertEqual(x, 1, m)), totalDevices=xform(lambda x, m: self.assertEqual(x, 5, m)))
self.stateCheck(self.dev19, - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), level=xform(lambda x, m: self.assertEqual(x.number, 1, m)), mdadmFormatUUID=xform(lambda x, m: self.assertEqual(x, blockdev.md.get_md_uuid(self.dev19.uuid), m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 2, m)), uuid=xform(lambda x, m: self.assertEqual(x, self.dev19.uuid, m)))
self.stateCheck(self.dev20, - devices=xform(lambda x, m: self.assertEqual(len(x), 2, m)), level=xform(lambda x, m: self.assertEqual(x.number, 1, m)), + members=xform(lambda x, m: self.assertEqual(len(x), 2, m)), parents=xform(lambda x, m: self.assertEqual(len(x), 2, m)), uuid=xform(lambda x, m: self.assertEqual(x, self.dev20.uuid, m)))