bdev: implement disk resize for lvm/drbd8
authorIustin Pop <iustin@google.com>
Mon, 16 Jun 2008 15:04:01 +0000 (15:04 +0000)
committerIustin Pop <iustin@google.com>
Mon, 16 Jun 2008 15:04:01 +0000 (15:04 +0000)
This patch implements disk resize at the bdev level for the LVM and
DRBD8 disk types. It is not implemented for DRBD7 and MD since the way
MD works with its underlaying devices makes it harder and this
combination is also deprecated.

The LVM resize operation is tried three times, with different allocation
policies:
  - contiguous first, since this is best for allocation purposes (it
    won't fragment too much the PV)
  - cling, which is supported only by more recent LVM versions, will try
    to place the new extents on the same PV as the rest of the LV
  - and finally normal, which is the default

Reviewed-by: imsnah

lib/bdev.py

index 5ca0fef..f3b182f 100644 (file)
@@ -279,6 +279,16 @@ class BlockDev(object):
     for child in self._children:
       child.SetInfo(text)
 
+  def Grow(self, amount):
+    """Grow the block device.
+
+    Arguments:
+      amount: the amount (in mebibytes) to grow with
+
+    Returns: None
+
+    """
+    raise NotImplementedError
 
   def __repr__(self):
     return ("<%s: unique_id: %s, children: %s, %s:%s, %s>" %
@@ -571,6 +581,21 @@ class LogicalVolume(BlockDev):
       raise errors.BlockDeviceError("Command: %s error: %s - %s" %
                                     (result.cmd, result.fail_reason,
                                      result.output))
+  def Grow(self, amount):
+    """Grow the logical volume.
+
+    """
+    # we try multiple algorithms since the 'best' ones might not have
+    # space available in the right place, but later ones might (since
+    # they have less constraints); also note that only recent LVM
+    # supports 'cling'
+    for alloc_policy in "contiguous", "cling", "normal":
+      result = utils.RunCmd(["lvextend", "--alloc", alloc_policy,
+                             "-L", "+%dm" % amount, self.dev_path])
+      if not result.failed:
+        return
+    raise errors.BlockDeviceError("Can't grow LV %s: %s" %
+                                  (self.dev_path, result.output))
 
 
 class MDRaid1(BlockDev):
@@ -2312,6 +2337,21 @@ class DRBD8(BaseDRBD):
       raise errors.BlockDeviceError("Cannot initalize meta device")
     return cls(unique_id, children)
 
+  def Grow(self, amount):
+    """Resize the DRBD device and its backing storage.
+
+    """
+    if self.minor is None:
+      raise errors.ProgrammerError("drbd8: Grow called while not attached")
+    if len(self._children) != 2 or None in self._children:
+      raise errors.BlockDeviceError("Cannot grow diskless DRBD8 device")
+    self._children[0].Grow(amount)
+    result = utils.RunCmd(["drbdsetup", self.dev_path, "resize"])
+    if result.failed:
+      raise errors.BlockDeviceError("resize failed for %s: %s" %
+                                    (self.dev_path, result.output))
+    return
+
 
 DEV_MAP = {
   constants.LD_LV: LogicalVolume,