"""Compute the number of PVs needed for an LV (with exclusive storage).
@type size: float
- @param size: LV size
+ @param size: LV size in MiB
@param pvs_info: list of objects.LvmPvInfo, cannot be empty
@rtype: integer
@return: number of PVs needed
return data
@classmethod
- def GetVGInfo(cls, vg_names, filter_readonly=True):
+ def _GetExclusiveStorageVgFree(cls, vg_name):
+ """Return the free disk space in the given VG, in exclusive storage mode.
+
+ @type vg_name: string
+ @param vg_name: VG name
+ @rtype: float
+ @return: free space in MiB
+ """
+ pvs_info = cls.GetPVInfo([vg_name])
+ if not pvs_info:
+ return 0.0
+ pv_size = cls._GetStdPvSize(pvs_info)
+ num_pvs = len(cls._GetEmptyPvNames(pvs_info))
+ return pv_size * num_pvs
+
+ @classmethod
+ def GetVGInfo(cls, vg_names, excl_stor, filter_readonly=True):
"""Get the free space info for specific VGs.
@param vg_names: list of volume group names, if empty all will be returned
+ @param excl_stor: whether exclusive_storage is enabled
@param filter_readonly: whether to skip over readonly VGs
@rtype: list
# (possibly) skip over vgs which are not in the right volume group(s)
if vg_names and vg_name not in vg_names:
continue
+ # Exclusive storage needs a different concept of free space
+ if excl_stor:
+ es_free = cls._GetExclusiveStorageVgFree(vg_name)
+ assert es_free <= vg_free
+ vg_free = es_free
data.append((float(vg_free), float(vg_size), vg_name))
return data
snap = LogicalVolume((self._vg_name, snap_name), None, size, self.params)
_IgnoreError(snap.Remove)
- vg_info = self.GetVGInfo([self._vg_name])
+ vg_info = self.GetVGInfo([self._vg_name], False)
if not vg_info:
_ThrowError("Can't compute VG info for vg %s", self._vg_name)
free_size, _, _ = vg_info[0]