commit 52a8a6ae5978411775666ee9144eae2481fc18c7
Author: Helga Velroyen <helgav@google.com>
Date:   Wed Jul 3 13:04:38 2013 +0200

    Fix propagation of storage parameters to/from backend
    
    This patch fixes two problems with the storage reporting
    that showed up in the QA for exclusive storage:
    
    - The processing of storage space information for instance
      operations wrongly assumed that the volume group's
      storage information is always the first in the list.
    - The storage parameter 'exclusive storage' was not
      correctly extracted from the list of storage parameters.
    - There was a bug in the preparation of storage unit for
      the node info call in the iallocator. The exclusive
      storage flag was not set for spindles and the format
      of the storage parameters for LVM vgs was a boolean
      and not a list.
    
    Signed-off-by: Helga Velroyen <helgav@google.com>
    Reviewed-by: Klaus Aehlig <aehlig@google.com>
    Reviewed-by: Michele Tartara <mtartara@google.com>

diff --git a/lib/backend.py b/lib/backend.py
index aea6db3..09b9984 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -573,6 +573,29 @@ def LeaveCluster(modify_ssh_setup):
   raise errors.QuitGanetiException(True, "Shutdown scheduled")
 
 
+def _GetLvmVgSpaceInfo(name, params):
+  """Wrapper around C{_GetVgInfo} which checks the storage parameters.
+
+  @type name: string
+  @param name: name of the volume group
+  @type params: list
+  @param params: list of storage parameters, which in this case should be
+    containing only one for exclusive storage
+
+  """
+  if params is None:
+    raise errors.ProgrammerError("No storage parameter for LVM vg storage"
+                                 " reporting is provided.")
+  if not isinstance(params, list):
+    raise errors.ProgrammerError("The storage parameters are not of type"
+                                 " list: '%s'" % params)
+  if not len(params) == 1:
+    raise errors.ProgrammerError("Received more than one storage parameter:"
+                                 " '%s'" % params)
+  excl_stor = bool(params[0])
+  return _GetVgInfo(name, excl_stor)
+
+
 def _GetVgInfo(name, excl_stor):
   """Retrieves information about a LVM volume group.
 
@@ -714,7 +737,7 @@ _STORAGE_TYPE_INFO_FN = {
   constants.ST_EXT: None,
   constants.ST_FILE: _GetFileStorageSpaceInfo,
   constants.ST_LVM_PV: _GetVgSpindlesInfo,
-  constants.ST_LVM_VG: _GetVgInfo,
+  constants.ST_LVM_VG: _GetLvmVgSpaceInfo,
   constants.ST_RADOS: None,
 }
 
diff --git a/lib/cmdlib/instance_storage.py b/lib/cmdlib/instance_storage.py
index f92eaaa..8b1db31 100644
--- a/lib/cmdlib/instance_storage.py
+++ b/lib/cmdlib/instance_storage.py
@@ -905,8 +905,12 @@ def _CheckNodesFreeDiskOnVG(lu, node_uuids, vg, requested):
     info = nodeinfo[node]
     info.Raise("Cannot get current information from node %s" % node_name,
                prereq=True, ecode=errors.ECODE_ENVIRON)
-    (_, (vg_info, ), _) = info.payload
-    vg_free = vg_info.get("storage_free", None)
+    (_, space_info, _) = info.payload
+    lvm_vg_info = utils.storage.LookupSpaceInfoByStorageType(
+        space_info, constants.ST_LVM_VG)
+    if not lvm_vg_info:
+      raise errors.OpPrereqError("Can't retrieve storage information for LVM")
+    vg_free = lvm_vg_info.get("storage_free", None)
     if not isinstance(vg_free, int):
       raise errors.OpPrereqError("Can't compute free disk space on node"
                                  " %s for vg %s, result was '%s'" %
diff --git a/lib/rpc.py b/lib/rpc.py
index 5ce530a..1058dcc 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -730,8 +730,8 @@ def _AddExclusiveStorageFlagToLvmStorageUnits(storage_units, es_flag):
   """
   result = []
   for (storage_type, storage_key) in storage_units:
-    if storage_type == constants.ST_LVM_VG:
-      result.append((storage_type, storage_key, es_flag))
+    if storage_type in [constants.ST_LVM_VG, constants.ST_LVM_PV]:
+      result.append((storage_type, storage_key, [es_flag]))
     else:
       result.append((storage_type, storage_key, []))
   return result
