Volume Groups (VG) are represented by, LMI_VGStoragePool class.
Every LMI_VGStoragePool instance has associated one instance of LMI_VGStorageSetting representing its configuration (e.g. volume group extent size) and one instance of LMI_LVStorageCapabilities, representing its ability to create logical volumes (for SMI-S applications).
Physical Volumes (PV) are associated to VGs using LMI_VGAssociatedComponentExtent association.
Logical Volumes (LV) are represented by LMI_LVStorageExtent class. Each LMI_LVStorageExtent instance is associated to its VG using LMI_LVAllocatedFromStoragePool association.
In addition, LVs are associated to all PVs using LMI_LVBasedOn association.
Following instance diagram shows one Volume Group /dev/myGroup based on three Physical Volumes /dev/sda1, /dev/sdb1 `` and ``/dev/sdc1 and two Logical Volumes myVol1 and myVol2.
Note that the diagram is simplified and does not show LMI_LVBasedOn association, which associates every myVolY to /dev/sdX1.
Currently the LVM support is limited to creation and removal of VGs and LVs. It is not possible to modify existing VG or LV, e.g. add or remove devices to/from VG and/or resize LVs. In future OpenLMI may be extended to have more configuration options in LMI_VGStorageSetting and LMI_LVStorageSetting.
Use CreateOrModifyVG method. Following example creates a VG ‘/dev/myGroup’ with three members and with default extent size (4MiB):
# Find the devices we want to add to VG
# (filtering one CIM_StorageExtent.instances()
# call would be faster, but this is easier to read)
sda1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sda1")
sdb1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sdb1")
sdc1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sdc1")
# Create the VG
(ret, outparams, err) = storage_service.CreateOrModifyVG(
ElementName = "myGroup",
InExtents= [sda1.path, sdb1.path, sdc1.path])
vg = outparams['pool'].to_instance()
print "VG", vg.PoolID, \
"with extent size", vg.ExtentSize, \
"and", vg.RemainingExtents, "free extents created."
The resulting VG is the same as shown in diagram above, except it does not have any LVs yet.
SMI-S applications can use CreateOrModifyStoragePool method. Following example creates a VG ‘/dev/myGroup’ with three members and with default extent size (4MiB):
# Find the devices we want to add to VG
# (filtering one CIM_StorageExtent.instances()
# call would be faster, but this is easier to read)
sda1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sda1")
sdb1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sdb1")
sdc1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sdc1")
# Create the VG
(ret, outparams, err) = storage_service.CreateOrModifyStoragePool(
InExtents=[sda1.path, sdb1.path, sdc1.path],
ElementName="myGroup")
vg = outparams['pool'].to_instance()
print "VG", vg.PoolID, \
"with extent size", vg.ExtentSize, \
"and", vg.RemainingExtents, "free extents created."
The resulting VG is the same as shown in diagram above, except it does not have any LVs yet.
Use CreateVGStorageSetting to create LMI_VGStorageSetting, modify its ExtentSize property with desired extent size and finally call CreateOrModifyVG with the setting as Goal parameter. Following example creates a VG ‘/dev/myGroup’ with three members and with 1MiB extent size (4MiB):
# Find the devices we want to add to VG
# (filtering one CIM_StorageExtent.instances()
# call would be faster, but this is easier to read)
sda1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sda1")
sdb1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sdb1")
sdc1 = root.CIM_StorageExtent.first_instance(
Key="DeviceID", Value="/dev/sdc1")
# Create the LMI_VGStorageSetting
vg_caps = root.LMI_VGStorageCapabilities.first_instance()
(ret, outparams, err) = vg_caps.CreateVGStorageSetting(
InExtents = [sda1.path, sdb1.path, sdc1.path])
setting = outparams['setting'].to_instance()
setting.ExtentSize = MEGABYTE
# TODO: modify the instance
# Create the VG
# (either of CreateOrModifyStoragePool or CreateOrModifyVG
# can be used with the same result)
(ret, outparams, err) = storage_service.CreateOrModifyStoragePool(
InExtents=[sda1.path, sdb1.path, sdc1.path],
ElementName="myGroup",
Goal = setting.path)
vg = outparams['pool'].to_instance()
print "VG", vg.PoolID, \
"with extent size", vg.ExtentSize, \
"and", vg.RemainingExtents, "free extents created."
Enumerate VGAssociatedComponentExtent associations of the VG.
Following code lists all PVs of /dev/myGroup:
# Find the disk
vg = root.LMI_VGStoragePool.first_instance(
Key="InstanceID", Value="LMI:VG:myGroup")
pvs = vg.associators(AssocClass="LMI_VGAssociatedComponentExtent")
for pv in pvs:
print "Found PV", pv.DeviceID
Use CreateOrModifyLV method. Following example creates two 100MiB volumes:
# Find the VG
vg = root.LMI_VGStoragePool.first_instance(
Key="InstanceID", Value="LMI:VG:myGroup")
# Create the LV
(ret, outparams, err) = storage_service.CreateOrModifyLV(
ElementName = "Vol1",
InPool = vg.path,
Size = 100 * MEGABYTE)
lv = outparams['theelement'].to_instance()
print "LV", lv.DeviceID, \
"with", lv.BlockSize * lv.NumberOfBlocks,\
"bytes created."
# Create the second LV
(ret, outparams, err) = storage_service.CreateOrModifyLV(
ElementName = "Vol2",
InPool = vg.path,
Size = 100 * MEGABYTE)
lv = outparams['theelement'].to_instance()
print "LV", lv.DeviceID, \
"with", lv.BlockSize * lv.NumberOfBlocks, \
"bytes created."
The resulting LVs are the same as shown in diagram above.
Use CreateOrModifyElementFromStoragePool method. The code is the same as in previous sample, just different method is used:
# Find the VG
vg = root.LMI_VGStoragePool.first_instance(
Key="InstanceID", Value="LMI:VG:myGroup")
# Create the LV
(ret, outparams, err) = storage_service.CreateOrModifyLV(
ElementName = "Vol1",
InPool = vg.path,
Size = 100 * MEGABYTE)
lv = outparams['theelement'].to_instance()
print "LV", lv.DeviceID, \
"with", lv.BlockSize * lv.NumberOfBlocks,\
"bytes created."
# Create the second LV
(ret, outparams, err) = storage_service.CreateOrModifyElementFromStoragePool(
ElementName = "Vol2",
InPool = vg.path,
Size = 100 * MEGABYTE)
lv = outparams['theelement'].to_instance()
print "LV", lv.DeviceID, \
"with", lv.BlockSize * lv.NumberOfBlocks, \
"bytes created."
In future, we might implement: