[blivet:master 25/26] Move the code for getting a space requirement from devicefactory to raid.
mulhern
amulhern at redhat.com
Thu May 29 18:47:43 UTC 2014
In devicelibs/raid.py make a new function called get_space which estimates
the space required for data and metadata. Make a few auxiliary functions.
mdraid now requires that its RAIDLevel objects supply get_space, rather
than get_base_member_size (which only made sense for RAIDLevel objects for
which uniform is True).
Signed-off-by: mulhern <amulhern at redhat.com>
---
blivet/devicefactory.py | 8 ++---
blivet/devicelibs/mdraid.py | 2 +-
blivet/devicelibs/raid.py | 68 +++++++++++++++++++++++++++++++++++---
tests/devicelibs_test/raid_test.py | 4 ---
4 files changed, 69 insertions(+), 13 deletions(-)
diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py
index a42622e..434f94a 100644
--- a/blivet/devicefactory.py
+++ b/blivet/devicefactory.py
@@ -1575,10 +1575,10 @@ class MDFactory(DeviceFactory):
raise DeviceFactoryError("MDFactory class must have some RAID level.")
def _get_device_space(self):
- member_count = len(self._get_member_devices())
- size_per_member = self.raid_level.get_base_member_size(self.size, member_count)
- size_per_member += mdraid.get_raid_superblock_size(self.size)
- return size_per_member * member_count
+ return self.raid_level.get_space(self.size,
+ len(self._get_member_devices()),
+ None,
+ mdraid.get_raid_superblock_size)
def _get_total_space(self):
return self._get_device_space()
diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py
index f0d8162..b82c43d 100644
--- a/blivet/devicelibs/mdraid.py
+++ b/blivet/devicelibs/mdraid.py
@@ -39,7 +39,7 @@ class MDRaidLevels(raid.RAIDLevels):
def isRaidLevel(cls, level):
return super(MDRaidLevels, cls).isRaidLevel(level) and \
hasattr(level, 'get_max_spares') and \
- hasattr(level, 'get_base_member_size') and \
+ hasattr(level, 'get_space') and \
hasattr(level, 'get_recommended_stride') and \
hasattr(level, 'get_size')
diff --git a/blivet/devicelibs/raid.py b/blivet/devicelibs/raid.py
index 6b05122..1ec4e07 100644
--- a/blivet/devicelibs/raid.py
+++ b/blivet/devicelibs/raid.py
@@ -200,6 +200,21 @@ class RAIDn(RAIDLevel):
"""
raise NotImplementedError()
+ @abc.abstractmethod
+ def _pad(self, size, chunk_size):
+ """Helper function; not to be called directly.
+
+ Pads size to the smallest size greater than size that is in units
+ of chunk_size.
+
+ :param size: the size of the array
+ :type size: :class:`~.size.Size`
+ :param chunk_size: the smallest unit of size this array allows
+ :type chunk_size: :class:`~.size.Size`
+ :rtype: :class:`~.size.Size`
+ """
+ raise NotImplementedError()
+
def get_recommended_stride(self, member_count):
"""Return a recommended stride size in blocks.
@@ -258,6 +273,31 @@ class RAIDn(RAIDLevel):
min_data_size = self._trim(min_size - superblock_size, chunk_size)
return self.get_net_array_size(num_members, min_data_size)
+ def get_space(self, size, num_members, chunk_size=None, superblock_size_func=None):
+ """Estimate the amount of memory required by this array, including
+ memory allocated for metadata.
+
+ :param size: the amount of data on this array
+ :type size: :class:`~.size.Size`
+ :param int num_members: the number of members in the array
+ :param chunk_size: the smallest unit of size for
+ :type chunk_size: :class:`~.size.Size`
+ :param superblock_size_func: a function that estimates the
+ superblock size for this array
+ :type superblock_size_func: a function from :class:`~.size.Size` to
+ :class:`~.size.Size`
+ :returns: an estimate of the memory required, including metadata
+ :rtype: :class:`~.size.Size`
+ """
+ if superblock_size_func is None:
+ raise RaidError("superblock_size_func value of None is not acceptable")
+
+ size_per_member = self.get_base_member_size(size, num_members)
+ size_per_member += superblock_size_func(size)
+ if chunk_size is not None:
+ size_per_member = self._pad(size_per_member, chunk_size)
+ return size_per_member * num_members
+
class RAIDLevels(object):
"""A class which keeps track of registered RAID levels. This class
may be extended, overriding the isRaid method to include any
@@ -358,6 +398,9 @@ class RAID0(RAIDn):
def _trim(self, size, chunk_size):
return size - size % chunk_size
+ def _pad(self, size, chunk_size):
+ return size + (chunk_size - (size % chunk_size)) % chunk_size
+
def _get_recommended_stride(self, member_count):
return member_count * 16
@@ -382,6 +425,9 @@ class RAID1(RAIDn):
def _trim(self, size, chunk_size):
return size
+ def _pad(self, size, chunk_size):
+ return size
+
def _get_recommended_stride(self, member_count):
return None
@@ -406,6 +452,9 @@ class RAID4(RAIDn):
def _trim(self, size, chunk_size):
return size - size % chunk_size
+ def _pad(self, size, chunk_size):
+ return size + (chunk_size - (size % chunk_size)) % chunk_size
+
def _get_recommended_stride(self, member_count):
return (member_count - 1) * 16
@@ -430,6 +479,9 @@ class RAID5(RAIDn):
def _trim(self, size, chunk_size):
return size - size % chunk_size
+ def _pad(self, size, chunk_size):
+ return size + (chunk_size - (size % chunk_size)) % chunk_size
+
def _get_recommended_stride(self, member_count):
return (member_count - 1) * 16
@@ -454,6 +506,9 @@ class RAID6(RAIDn):
def _trim(self, size, chunk_size):
return size - size % chunk_size
+ def _pad(self, size, chunk_size):
+ return size + (chunk_size - (size % chunk_size)) % chunk_size
+
def _get_recommended_stride(self, member_count):
return None
@@ -478,6 +533,9 @@ class RAID10(RAIDn):
def _trim(self, size, chunk_size):
return size
+ def _pad(self, size, chunk_size):
+ return size + (chunk_size - (size % chunk_size)) % chunk_size
+
def _get_recommended_stride(self, member_count):
return None
@@ -494,9 +552,9 @@ class Container(RAIDLevel):
def get_max_spares(self, member_count):
# pylint: disable=unused-argument
raise RaidError("get_max_spares is not defined for level container")
- def get_base_member_size(self, size, member_count):
+ def get_space(self, size, num_members, chunk_size=None, superblock_size_func=None):
# pylint: disable=unused-argument
- raise RaidError("get_base_member_size is not defined for level container")
+ return size
def get_recommended_stride(self, member_count):
# pylint: disable=unused-argument
raise RaidError("get_recommended_stride is not defined for level container")
@@ -522,9 +580,11 @@ class ErsatzRAID(RAIDLevel):
def get_max_spares(self, member_count):
return member_count - self.min_members
- def get_base_member_size(self, size, member_count):
+ def get_space(self, size, num_members, chunk_size=None, superblock_size_func=None):
# pylint: disable=unused-argument
- raise RaidError("get_base_member_size is not defined for level linear")
+ if superblock_size_func is None:
+ raise RaidError("superblock_size_func value of None is not acceptable")
+ return size + num_members * superblock_size_func(size)
def get_recommended_stride(self, member_count):
# pylint: disable=unused-argument
diff --git a/tests/devicelibs_test/raid_test.py b/tests/devicelibs_test/raid_test.py
index 35c912a..4715268 100644
--- a/tests/devicelibs_test/raid_test.py
+++ b/tests/devicelibs_test/raid_test.py
@@ -79,10 +79,6 @@ class RaidTestCase(unittest.TestCase):
4, 3)
self.assertRaises(errors.RaidError, raid.RAID10.get_base_member_size,
-4, 4)
- self.assertRaisesRegexp(errors.RaidError,
- "not defined",
- raid.Linear.get_base_member_size,
- 4, 3)
##
## get_net_array_size
--
1.8.3.1
More information about the anaconda-patches
mailing list