[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