[rhel6] Shrink the LV if the VG is out of space (#1153376)

Brian C. Lane bcl at redhat.com
Fri Dec 5 20:27:51 UTC 2014


lvm doesn't always create the sizes that we expect it to. This can lead
to errors like this:

Volume group "VolGroup" has insufficient free space (1965 extents): 1968
required.

This change checks the LV's size against the VG's actual free space and
shrinks the LV to fit if it would be to big.

This is a port of commit 0c40779fa8f from python-blivet.

Resolves: rhbz#1153376
---
 storage/devices.py | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/storage/devices.py b/storage/devices.py
index e179339..8bdf2a5 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -2545,6 +2545,36 @@ class LVMLogicalVolumeDevice(DMDevice):
 
         return [validpvs[0].path]
 
+    def _preCreate(self):
+        """ Adjust the size of the LV if there isn't enough space in the VG.
+
+        size calculations sometimes don't match what lvm actually creates,
+        so check the actual free space of the VG and use that if the LV is
+        too big.
+        """
+        try:
+            vg_info = lvm.vginfo(self.vg.name)
+        except errors.LVMError as lvmerr:
+            log.error("Failed to get free space for the %s VG: %s", self.vg.name, lvmerr)
+            # nothing more can be done, we don't know the VG's free space
+            return
+
+        try:
+            extent_size = float(vg_info["pe_size"])
+            extents_free = int(vg_info["pe_free"])
+        except ValueError as e:
+            log.error("Failed to get PE information for the %s VG: %s", self.vg.name, e)
+            return
+
+        log.debug("VG has %s free PEs of size %s", extents_free, extent_size)
+
+        can_use = extent_size * extents_free
+        if self.size > can_use:
+            msg = ("%s LV's size (%s) exceeds the VG's usable free space (%s),"
+                    "shrinking the LV") % (self.name, self.size, can_use)
+            log.warning(msg)
+            self.size = can_use
+
     def create(self, intf=None):
         """ Create the device. """
         log_method_call(self, self.name, status=self.status)
@@ -2561,6 +2591,9 @@ class LVMLogicalVolumeDevice(DMDevice):
             self.createParents()
             self.setupParents()
 
+            # Make sure the LV will fit into the real VG size
+            self._preCreate()
+
             # should we use --zero for safety's sake?
             if self.singlePV:
                 lvm.lvcreate(self.vg.name, self._name, self.size, progress=w,
-- 
1.9.3



More information about the anaconda-patches mailing list