[blivet:rhel7/master 3/3] Set up Blivet.resizeDevice() to handle LUKS devices (#1076055)

mulhern amulhern at redhat.com
Wed Sep 24 16:12:58 UTC 2014


Previously, resizeDevice() could not resize a LUKS device.
A LUKS device is just a kind of veneer over its slave device and is the
only kind of devices such that device.raw_device is not device.

blivet does not currently implement a resize() method for LUKSDevice and in
the general case, it is always necessary to resize the raw_device in order
to resize the LUKSDevice itself. However, when blivet is able to resize the
LUKS Device, which at this point is exactly when the LUKSDevice does not
yet exist and its raw_device is resizable, resizeDevice() should be able to
do it.

Also, calculate some derived quantities besides size from the values
of the underlying device in LUKSDevice.

Use the device format's minSize to find the difference between the raw
device's size quantity and the LUKS devices size quantity instead of using
crypto.LUKS_METADATA_SIZE.

Signed-off-by: mulhern <amulhern at redhat.com>
---
 blivet/__init__.py | 24 ++++++++++++++++++++++++
 blivet/devices.py  | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/blivet/__init__.py b/blivet/__init__.py
index 210f423..fe7cbbe 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -1353,6 +1353,30 @@ class Blivet(object):
             If the device has formatting that is recognized as being resizable
             an action will be scheduled to resize it as well.
         """
+        # If the device is not resizable and it exists then
+        # resizing the raw device is not enough to complete the
+        # resize step, best to quit.
+        if device.exists and not device.resizable:
+            raise ValueError("device cannot be resized")
+
+        # Currently the code base only contains one type of device where
+        # device != device.raw_device, LUKSDevice. No resize() method is
+        # implemented for LUKSDevice, so resizable is always False and so
+        # in the current code base this condition must always be False.
+        # If this condition ever becomes True then this method will have to
+        # be extended to handle setting up resize actions for the device
+        # proper as well as its raw device.
+        if device is not device.raw_device and device.resizable:
+            raise NotImplementedError("previously impossible situation.")
+
+        # The new size of the raw device must be larger than the specified
+        # size for the device proper by the space required for that device's
+        # metadata.
+        if device is not device.raw_device:
+            new_size += device.format.minSize
+
+        device = device.raw_device
+
         classes = []
         if device.resizable:
             classes.append(ActionResizeDevice)
diff --git a/blivet/devices.py b/blivet/devices.py
index 2cfeac4..9be3fd5 100644
--- a/blivet/devices.py
+++ b/blivet/devices.py
@@ -2344,13 +2344,42 @@ class LUKSDevice(DMCryptDevice):
         return self.slave
 
     @property
+    def maxSize(self):
+        max_size = self.slave.maxSize
+        if not max_size:
+            return max_size
+
+        max_size = max_size - self.format.minSize
+        if max_size < 0:
+            return 0
+
+        return max_size
+
+    @property
+    def minSize(self):
+        return self.slave.minSize + self.format.minSize
+
+    @property
     def size(self):
         if not self.exists or not self.partedDevice:
-            size = self.slave.size - crypto.LUKS_METADATA_SIZE
+            size = self.slave.size - self.format.minSize
         else:
             size = Size(self.partedDevice.getLength(unit="B"))
         return size
 
+    def _setSize(self, size):
+        self.slave.size = size + self.format.minSize
+
+    def _setTargetSize(self, newsize):
+        self.slave._setTargetSize(newsize + self.format.minSize)
+
+    def _getTargetSize(self):
+        return self.slave._getTargetSize() - self.format.minSize
+
+    @property
+    def currentSize(self):
+        return self.slave.currentSize + self.format.minSize
+
     def _postCreate(self):
         self.name = self.slave.format.mapName
         StorageDevice._postCreate(self)
-- 
1.9.3



More information about the anaconda-patches mailing list