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 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sda1"})
sdb1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdb1"})
sdc1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdc1"})
# Create the VG
(ret, outparams, err) = storage_service.SyncCreateOrModifyVG(
ElementName="myGroup",
InExtents=[sda1, sdb1, sdc1])
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 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sda1"})
sdb1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdb1"})
sdc1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdc1"})
# Create the VG
(ret, outparams, err) = storage_service.SyncCreateOrModifyStoragePool(
InExtents=[sda1, sdb1, sdc1],
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 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sda1"})
sdb1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdb1"})
sdc1 = ns.CIM_StorageExtent.first_instance({"Name": "/dev/sdc1"})
# Create the LMI_VGStorageSetting
vg_caps = ns.LMI_VGStorageCapabilities.first_instance()
(ret, outparams, err) = vg_caps.CreateVGStorageSetting(
InExtents = [sda1, sdb1, sdc1])
setting = outparams['Setting'].to_instance()
# Modify the LMI_VGStorageSetting
setting.ExtentSize = MEGABYTE
settinh.push()
# Create the VG
# (either of CreateOrModifyStoragePool or CreateOrModifyVG
# can be used with the same result)
(ret, outparams, err) = storage_service.SyncCreateOrModifyStoragePool(
InExtents=[sda1, sdb1, sdc1],
ElementName="myGroup",
Goal=setting)
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 VG
vg = ns.LMI_VGStoragePool.first_instance({"Name": "/dev/mapper/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 = ns.LMI_VGStoragePool.first_instance({"Name": "/dev/mapper/myGroup"})
# Create the LV
(ret, outparams, err) = storage_service.SyncCreateOrModifyLV(
ElementName="Vol1",
InPool=vg,
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.SyncCreateOrModifyLV(
ElementName="Vol2",
InPool=vg,
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 = ns.LMI_VGStoragePool.first_instance({"Name": "/dev/mapper/myGroup"})
# Create the LV
(ret, outparams, err) = storage_service.SyncCreateOrModifyElementFromStoragePool(
ElementName="Vol1",
InPool=vg,
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.SyncCreateOrModifyElementFromStoragePool(
ElementName="Vol2",
InPool=vg,
Size=100 * MEGABYTE)
lv = outparams['TheElement'].to_instance()
print "LV", lv.DeviceID, \
"with", lv.BlockSize * lv.NumberOfBlocks, \
"bytes created."
In future, we might implement: