[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 1/2] Prevent singlePV lv requests from being > the size of any pv



This was working fine, but needed some additional checks to prevent it
from happening in manual partitioning mode.  Simplify the getSinglePV()
method so it reads the pv information from the Storage object rather
than parsing the output of the 'lvs pvs' command.

Related: rhbz#618376
---
 iw/lvm_dialog_gui.py |   22 +++++++++++++++++---
 storage/devices.py   |   51 +++++++++++++++++++++----------------------------
 2 files changed, 40 insertions(+), 33 deletions(-)

diff --git a/iw/lvm_dialog_gui.py b/iw/lvm_dialog_gui.py
index 1ceebd7..29c3d81 100644
--- a/iw/lvm_dialog_gui.py
+++ b/iw/lvm_dialog_gui.py
@@ -1081,14 +1081,28 @@ class VolumeGroupEditor:
             log.debug("new lv %s" % lv)
             if not lv.exists:
                 log.debug("creating lv %s" % lv.lvname)
+                mountpoint = getattr(lv.format, "mountpoint", None)
+                singlepv = False
+
+                if iutil.isS390() and mountpoint == '/boot':
+                    singlepv = True
+
                 # create the device
-                newlv = LVMLogicalVolumeDevice(lv.lvname,
-                                               self.vg,
-                                               size=lv.size)
+                try:
+                    newlv = LVMLogicalVolumeDevice(lv.lvname,
+                                                   self.vg,
+                                                   size=lv.size,
+                                                   singlePV=singlepv)
+                except SinglePhysicalVolumeError, msg:
+                    self.intf.messageWindow(_("Error Partitioning"),
+                                            _("Could not allocate requested "
+                                              "logical volumes:\n\n%s.") % (msg),
+                                            custom_icon="error")
+                    continue
+
                 actions.append(ActionCreateDevice(newlv))
 
                 # create the format
-                mountpoint = getattr(lv.format, "mountpoint", None)
                 format = getFormat(lv.format.type,
                                    mountpoint=mountpoint,
                                    device=newlv.path)
diff --git a/storage/devices.py b/storage/devices.py
index 0383220..0d81343 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -2296,6 +2296,15 @@ class LVMLogicalVolumeDevice(DMDevice):
                           sysfsPath=sysfsPath, parents=vgdev,
                           exists=exists)
 
+        self.singlePVerr = ("%(mountpoint)s is restricted to a single "
+                            "physical volume on this platform.  No physical "
+                            "volumes available in volume group %(vgname)s "
+                            "with %(size)d MB of available space." %
+                           {'mountpoint': getattr(self.format, "mountpoint",
+                                                  "A proposed logical volume"),
+                            'vgname': self.vg.name,
+                            'size': self.size})
+
         self.uuid = uuid
         self.snapshotSpace = snapshotSpace
         self.stripes = stripes
@@ -2314,6 +2323,13 @@ class LVMLogicalVolumeDevice(DMDevice):
             self.req_size = self._size
             self.req_percent = numeric_type(percent)
 
+        if self.singlePV:
+            # make sure there is at least one PV that can hold this LV
+            validpvs = filter(lambda x: float(x.size) >= self.req_size,
+                              self.vg.pvs)
+            if not validpvs:
+                raise SinglePhysicalVolumeError(self.singlePVerr)
+
         # here we go with the circular references
         self.vg._addLogVol(self)
 
@@ -2469,35 +2485,12 @@ class LVMLogicalVolumeDevice(DMDevice):
                 log.debug("vg %s teardown failed; continuing" % self.vg.name)
 
     def _getSinglePV(self):
-        # NOTE: This runs the pvs(8) command and outputs the PV device
-        # name, VG name, and amount of free space on the PV in megabytes.
-        # A change to the Size class will require more handling of the
-        # units switch in this arg list.
-        args = ["pvs", "--noheadings", "--nosuffix", "--aligned",
-                "--units", "M", "-o", "pv_name,vg_name,pv_free"]
-        buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5")
-
-        for line in buf.splitlines():
-            fields = filter(lambda x: x != '', line.strip().split())
-
-            if len(fields) != 3 or fields[1] != self.vg.name:
-                continue
-            if float(fields[2]) >= self.size:
-                return [fields[0]]             # lvm.lvcreate needs a list
-
-        if hasattr(self.format, "mountpoint"):
-            mountpoint = self.format.mountpoint
-        else:
-            mountpoint = self.format.name
-
-        raise SinglePhysicalVolumeError("Single physical volume restriction "
-                                        "for %(mountpoint)s on this platform. "
-                                        "No physical volumes available in "
-                                        "volume group %(vgname)s with "
-                                        "%(size)d MB of available space."
-                                        % {'mountpoint': mountpoint,
-                                           'vgname': self.vg.name,
-                                           'size': self.size})
+        validpvs = filter(lambda x: float(x.size) >= self.size, self.vg.pvs)
+
+        if not validpvs:
+            raise SinglePhysicalVolumeError(self.singlePVerr)
+
+        return [validpvs[0].path]
 
     def create(self, intf=None):
         """ Create the device. """
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]