From 6d33a6eb4af6e2084ad5beeb93c4c09cc67f0868 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Thu, 13 Jan 2011 16:51:57 +0100
Subject: [PATCH] Fix growing of DRBD disks

Patch 03941a26 made disk growth VG-aware, but the code has a bug: it
only works for LD_LV disks, and not LD_DRBD. To fix it, we add a
generic function to compute the per-VG growth requirements, and switch
to using that instead of manual build.

Furthermore, since the function _CheckNodesFreeDiskPerVG always takes
its input from this new function or _ComputeDiskSizePerVG, we change
the latter to always return a dict (possibly empty), instead of either
a dict or None. This makes the types more consistent.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/cmdlib.py  | 11 +++++------
 lib/objects.py | 24 +++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index e989b2316..e08d903dc 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -4907,9 +4907,8 @@ def _CheckNodesFreeDiskPerVG(lu, nodenames, req_sizes):
       or we cannot check the node
 
   """
-  if req_sizes is not None:
-    for vg, req_size in req_sizes.iteritems():
-      _CheckNodesFreeDiskOnVG(lu, nodenames, vg, req_size)
+  for vg, req_size in req_sizes.items():
+    _CheckNodesFreeDiskOnVG(lu, nodenames, vg, req_size)
 
 
 def _CheckNodesFreeDiskOnVG(lu, nodenames, vg, requested):
@@ -6686,11 +6685,11 @@ def _ComputeDiskSizePerVG(disk_template, disks):
 
   # Required free disk space as a function of disk and swap space
   req_size_dict = {
-    constants.DT_DISKLESS: None,
+    constants.DT_DISKLESS: {},
     constants.DT_PLAIN: _compute(disks, 0),
     # 128 MB are added for drbd metadata for each disk
     constants.DT_DRBD8: _compute(disks, 128),
-    constants.DT_FILE: None,
+    constants.DT_FILE: {},
   }
 
   if disk_template not in req_size_dict:
@@ -8646,7 +8645,7 @@ class LUGrowDisk(LogicalUnit):
       # TODO: check the free disk space for file, when that feature
       # will be supported
       _CheckNodesFreeDiskPerVG(self, nodenames,
-                               {self.disk.physical_id[0]: self.op.amount})
+                               self.disk.ComputeGrowth(self.op.amount))
 
   def Exec(self, feedback_fn):
     """Execute disk grow.
diff --git a/lib/objects.py b/lib/objects.py
index 274c75641..ce1521c5e 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -528,6 +528,28 @@ class Disk(ConfigObject):
             # be different)
     return result
 
+  def ComputeGrowth(self, amount):
+    """Compute the per-VG growth requirements.
+
+    This only works for VG-based disks.
+
+    @type amount: integer
+    @param amount: the desired increase in (user-visible) disk space
+    @rtype: dict
+    @return: a dictionary of volume-groups and the required size
+
+    """
+    if self.dev_type == constants.LD_LV:
+      return {self.logical_id[0]: amount}
+    elif self.dev_type == constants.LD_DRBD8:
+      if self.children:
+        return self.children[0].ComputeGrowth(amount)
+      else:
+        return {}
+    else:
+      # Other disk types do not require VG space
+      return {}
+
   def RecordGrow(self, amount):
     """Update the size of this disk after growth.
 
-- 
GitLab