[PATCH 2/2] Add support for preexisting lvm using raid segment types. (#873281)
David Lehman
dlehman at redhat.com
Wed Aug 7 21:28:36 UTC 2013
---
iw/lvm_dialog_gui.py | 18 ++++++----
iw/partition_gui.py | 3 +-
storage/devicelibs/lvm.py | 30 +++++++++--------
storage/devices.py | 22 ++++++++-----
storage/devicetree.py | 84 +++++++++++++++++++++++------------------------
storage/udev.py | 8 +++++
6 files changed, 92 insertions(+), 73 deletions(-)
diff --git a/iw/lvm_dialog_gui.py b/iw/lvm_dialog_gui.py
index cd1e11b..629c829 100644
--- a/iw/lvm_dialog_gui.py
+++ b/iw/lvm_dialog_gui.py
@@ -50,10 +50,11 @@ class VolumeGroupEditor:
for lv in self.lvs.values():
_l = LVMLogicalVolumeDevice(lv['name'], vg, format=lv['format'],
size=lv['size'], exists=lv['exists'],
- stripes=lv['stripes'],
+ copies=lv['copies'],
logSize=lv['logSize'],
snapshotSpace=lv['snapshotSpace'])
_l.originalFormat = lv['originalFormat']
+ _l.metaDataSize = lv['metaDataSize']
return vg
@@ -117,8 +118,8 @@ class VolumeGroupEditor:
resize = False
for lv in self.lvs.values():
# total space required by an lv may be greater than lv size.
- vg_space = lv['size'] * lv['stripes'] + lv['logSize'] \
- + lv['snapshotSpace']
+ vg_space = lv['size'] * lv['copies'] + lv['logSize'] \
+ + lv['snapshotSpace'] + lv['metaDataSize']
clamped_vg_space = lvm.clampSize(vg_space, newpe, roundup=1)
used += clamped_vg_space
if lv['size'] != lvm.clampSize(lv['size'], newpe, roundup=1):
@@ -464,7 +465,7 @@ class VolumeGroupEditor:
lvsizeentry.set_text("%Ld" % lv['size'])
# Maximum size label
- max_grow = tempvg.freeSpace / lv['stripes']
+ max_grow = tempvg.freeSpace / lv['copies']
maxsizelabel = createAlignedLabel(_("(Max size is %s MB)") %
min(lvm.getMaxLVSize(),
lv['size'] + max_grow))
@@ -812,8 +813,9 @@ class VolumeGroupEditor:
'size': templv.size,
'format': templv.format,
'originalFormat': templv.originalFormat,
- 'stripes': templv.stripes,
+ 'copies': templv.copies,
'logSize': templv.logSize,
+ 'metaDataSize': templv.metaDataSize,
'snapshotSpace': templv.snapshotSpace,
'exists': templv.exists}
if self.lvs.has_key(origname) and origname != templv.lvname:
@@ -864,8 +866,9 @@ class VolumeGroupEditor:
'size': free,
'format': format,
'originalFormat': format,
- 'stripes': 1,
+ 'copies': 1,
'logSize': 0,
+ 'metaDataSize': 0,
'snapshotSpace': 0,
'exists': False}
self.editLogicalVolume(self.lvs[name], isNew = 1)
@@ -1303,8 +1306,9 @@ class VolumeGroupEditor:
"size": lv.size,
"format": copy.copy(lv.format),
"originalFormat": lv.originalFormat,
- "stripes": lv.stripes,
+ "copies": lv.copies,
"logSize": lv.logSize,
+ "metaDataSize": lv.metaDataSize,
"snapshotSpace": lv.snapshotSpace,
"exists": lv.exists}
diff --git a/iw/partition_gui.py b/iw/partition_gui.py
index 2622dcd..3751c5e 100644
--- a/iw/partition_gui.py
+++ b/iw/partition_gui.py
@@ -1804,8 +1804,9 @@ class PartitionWindow(InstallWindow):
'size': vg.freeSpace,
'format': format,
'originalFormat': format,
- 'stripes': 1,
+ 'copies': 1,
'logSize': 0,
+ 'metaDataSize': 0,
'snapshotSpace': 0,
'exists': False}
lv = vgeditor.lvs[name]
diff --git a/storage/devicelibs/lvm.py b/storage/devicelibs/lvm.py
index 2b34da3..c4ad88d 100644
--- a/storage/devicelibs/lvm.py
+++ b/storage/devicelibs/lvm.py
@@ -328,9 +328,10 @@ def vginfo(vg_name):
return d
def lvs(vg_name):
- args = ["lvs", "--noheadings", "--nosuffix"] + \
- ["--units", "m"] + \
- ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
+ args = ["lvs",
+ "-a", "--unit", "k", "--nosuffix", "--nameprefixes", "--rows",
+ "--unquoted", "--noheadings",
+ "-olv_name,lv_uuid,lv_size,lv_attr,segtype"] + \
config_args + \
[vg_name]
@@ -338,20 +339,21 @@ def lvs(vg_name):
args,
stderr="/dev/tty5")
- lvs = {}
- for line in buf.splitlines():
- line = line.strip()
- if not line:
+ _vars = buf.split()
+ info = {}
+ for var in _vars:
+ (name, equals, value) = var.partition("=")
+ if not equals:
continue
- (name, uuid, size, attr) = line.split()
- lvs[name] = {"size": size,
- "uuid": uuid,
- "attr": attr}
- if not lvs:
- raise LVMError(_("lvs failed for %s" % vg_name))
+ val = value.strip()
+
+ if name not in info:
+ info[name] = []
- return lvs
+ info[name].append(val)
+
+ return info
def lvorigin(vg_name, lv_name):
args = ["lvs", "--noheadings", "-o", "origin"] + \
diff --git a/storage/devices.py b/storage/devices.py
index 02d73ee..1c99ac8 100644
--- a/storage/devices.py
+++ b/storage/devices.py
@@ -1870,6 +1870,7 @@ class LVMVolumeGroupDevice(DMDevice):
self.lv_uuids = []
self.lv_sizes = []
self.lv_attr = []
+ self.lv_types = []
self.hasDuplicate = False
self.reserved_percent = 0
self.reserved_space = 0
@@ -2301,7 +2302,7 @@ class LVMLogicalVolumeDevice(DMDevice):
_packages = ["lvm2"]
def __init__(self, name, vgdev, size=None, uuid=None,
- stripes=1, logSize=0, snapshotSpace=0,
+ copies=1, logSize=0, snapshotSpace=0, segType=None,
format=None, exists=None, sysfsPath='',
grow=None, maxsize=None, percent=None,
singlePV=False):
@@ -2316,13 +2317,14 @@ class LVMLogicalVolumeDevice(DMDevice):
size -- the device's size (in MB)
uuid -- the device's UUID
- stripes -- number of copies in the vg (>1 for mirrored lvs)
+ copies -- number of copies in the vg (>1 for mirrored lvs)
logSize -- size of log volume (for mirrored lvs)
snapshotSpace -- sum of sizes of snapshots of this lv
sysfsPath -- sysfs device path
format -- a DeviceFormat instance
exists -- indicates whether this is an existing device
singlePV -- if true, maps this lv to a single pv
+ segType -- segment type (eg: "linear", "raid1")
For new (non-existent) LVs only:
@@ -2353,9 +2355,11 @@ class LVMLogicalVolumeDevice(DMDevice):
self.uuid = uuid
self.snapshotSpace = snapshotSpace
- self.stripes = stripes
+ self.copies = copies
self.logSize = logSize
+ self.metaDataSize = 0
self.singlePV = singlePV
+ self.segType = segType or "linear"
self.req_grow = None
self.req_max_size = 0
@@ -2382,11 +2386,11 @@ class LVMLogicalVolumeDevice(DMDevice):
def __str__(self):
s = DMDevice.__str__(self)
s += (" VG device = %(vgdev)r percent = %(percent)s\n"
- " mirrored = %(mirrored)s stripes = %(stripes)d"
+ " segment type = %(type)s copies = %(copies)d"
" snapshot total = %(snapshots)dMB\n"
" VG space used = %(vgspace)dMB" %
{"vgdev": self.vg, "percent": self.req_percent,
- "mirrored": self.mirrored, "stripes": self.stripes,
+ "type": self.segType, "copies": self.copies,
"snapshots": self.snapshotSpace, "vgspace": self.vgSpaceUsed })
return s
@@ -2394,7 +2398,7 @@ class LVMLogicalVolumeDevice(DMDevice):
def dict(self):
d = super(LVMLogicalVolumeDevice, self).dict
if self.exists:
- d.update({"mirrored": self.mirrored, "stripes": self.stripes,
+ d.update({"copies": self.copies,
"snapshots": self.snapshotSpace,
"vgspace": self.vgSpaceUsed})
else:
@@ -2430,7 +2434,7 @@ class LVMLogicalVolumeDevice(DMDevice):
@property
def mirrored(self):
- return self.stripes > 1
+ return self.copies > 1
def _setSize(self, size):
size = self.vg.align(numeric_type(size))
@@ -2447,8 +2451,8 @@ class LVMLogicalVolumeDevice(DMDevice):
@property
def vgSpaceUsed(self):
""" Space occupied by this LV, not including snapshots. """
- return (self.vg.align(self.size, roundup=True) * self.stripes
- + self.logSize)
+ return (self.vg.align(self.size, roundup=True) * self.copies
+ + self.logSize + self.metaDataSize)
@property
def vg(self):
diff --git a/storage/devicetree.py b/storage/devicetree.py
index ba85aab..310f955 100644
--- a/storage/devicetree.py
+++ b/storage/devicetree.py
@@ -1516,15 +1516,22 @@ class DeviceTree(object):
def handleVgLvs(self, vg_device):
ret = False
vg_name = vg_device.name
- lv_names = vg_device.lv_names
- lv_uuids = vg_device.lv_uuids
- lv_sizes = vg_device.lv_sizes
- lv_attr = vg_device.lv_attr
if not vg_device.complete:
log.warning("Skipping LVs for incomplete VG %s" % vg_name)
return False
+ lv_info = devicelibs.lvm.lvs(vg_name)
+ try:
+ lv_names = udev_device_get_lv_names(lv_info)
+ lv_uuids = udev_device_get_lv_uuids(lv_info)
+ lv_sizes = udev_device_get_lv_sizes(lv_info)
+ lv_attr = udev_device_get_lv_attr(lv_info)
+ lv_types = udev_device_get_lv_types(lv_info)
+ except KeyError as e:
+ log.warning("invalid data for VG %s: %s" % (vg_name, e))
+ return
+
if not lv_names:
log.debug("no LVs listed for VG %s" % vg_name)
return False
@@ -1548,9 +1555,12 @@ class DeviceTree(object):
# the end
indices = range(len(lv_names))
indices.sort(key=lambda i: lv_attr[i], cmp=lv_attr_cmp)
- mirrors = {}
+ raid = {}
for index in indices:
lv_name = lv_names[index]
+ if not lv_name:
+ continue
+
name = "%s-%s" % (vg_name, lv_name)
if lv_attr[index][0] in 'Ss':
log.debug("found lvm snapshot volume '%s'" % name)
@@ -1581,29 +1591,39 @@ class DeviceTree(object):
continue
elif lv_attr[index][0] in 'Ii':
# mirror image
- lv_name = re.sub(r'_mimage.+', '', lv_name[1:-1])
+ lv_name = re.sub(r'_[rm]image.+', '', lv_name[1:-1])
name = "%s-%s" % (vg_name, lv_name)
- if name not in mirrors:
- mirrors[name] = {"stripes": 0, "log": 0}
+ if name not in raid:
+ raid[name] = {"copies": 0, "log": 0, "meta": 0}
- mirrors[name]["stripes"] += 1
+ raid[name]["copies"] += 1
+ continue
+ elif lv_attr[index][0] == 'e':
+ # raid metadata volume
+ lv_name = re.sub(r'_rmeta.+', '', lv_name[1:-1])
+ name = "%s-%s" % (vg_name, lv_name)
+ raid[name]["meta"] += lv_sizes[index]
+ continue
elif lv_attr[index][0] == 'l':
# log volume
lv_name = re.sub(r'_mlog.*', '', lv_name[1:-1])
name = "%s-%s" % (vg_name, lv_name)
- if name not in mirrors:
- mirrors[name] = {"stripes": 0, "log": 0}
+ if name not in raid:
+ raid[name] = {"copies": 0, "log": 0, "meta": 0}
- mirrors[name]["log"] = lv_sizes[index]
+ raid[name]["log"] = lv_sizes[index]
+ continue
- lv_dev = self.getDeviceByName(name)
- if lv_dev is None:
+ lv_device = self.getDeviceByName(name)
+ if lv_device is None:
lv_uuid = lv_uuids[index]
lv_size = lv_sizes[index]
+ lv_type = lv_types[index]
lv_device = LVMLogicalVolumeDevice(lv_name,
vg_device,
uuid=lv_uuid,
size=lv_size,
+ segType=lv_type,
exists=True)
self._addDevice(lv_device)
@@ -1614,13 +1634,15 @@ class DeviceTree(object):
log.info("setup of %s failed: %s"
% (lv_device.name, msg))
- for name, mirror in mirrors.items():
+ for name, data in raid.items():
lv_dev = self.getDeviceByName(name)
- lv_dev.stripes = mirror["stripes"]
- lv_dev.logSize = mirror["log"]
- log.debug("set %s stripes to %d, log size to %dMB, total size %dMB"
- % (lv_dev.name, lv_dev.stripes, lv_dev.logSize,
- lv_dev.vgSpaceUsed))
+ lv_dev.copies = data["copies"]
+ lv_dev.metaDataSize = data["meta"]
+ lv_dev.logSize = data["log"]
+ log.debug("set %s copies to %d, metadata size to %dMB, log size "
+ "to %dMB, total size %dMB"
+ % (lv_dev.name, lv_dev.copies, lv_dev.metaDataSize,
+ lv_dev.logSize, lv_dev.vgSpaceUsed))
return ret
@@ -1661,28 +1683,6 @@ class DeviceTree(object):
exists=True)
self._addDevice(vg_device)
- # Now we add any lv info found in this pv to the vg_device, we
- # do this for all pvs as pvs only contain lv info for lvs which they
- # contain themselves
- try:
- lv_names = udev_device_get_lv_names(info)
- lv_uuids = udev_device_get_lv_uuids(info)
- lv_sizes = udev_device_get_lv_sizes(info)
- lv_attr = udev_device_get_lv_attr(info)
- except KeyError as e:
- log.warning("invalid data for %s: %s" % (device.name, e))
- return
-
- for i in range(len(lv_names)):
- # Skip empty and already added lvs
- if not lv_names[i] or lv_names[i] in vg_device.lv_names:
- continue
-
- vg_device.lv_names.append(lv_names[i])
- vg_device.lv_uuids.append(lv_uuids[i])
- vg_device.lv_sizes.append(lv_sizes[i])
- vg_device.lv_attr.append(lv_attr[i])
-
def handleUdevMDMemberFormat(self, info, device):
log_method_call(self, name=device.name, type=device.format.type)
# either look up or create the array device
diff --git a/storage/udev.py b/storage/udev.py
index b7983af..e6455c8 100644
--- a/storage/udev.py
+++ b/storage/udev.py
@@ -399,6 +399,14 @@ def udev_device_get_lv_attr(info):
attr = [attr]
return attr
+def udev_device_get_lv_types(info):
+ segtypes = info['LVM2_SEGTYPE']
+ if not segtypes:
+ segtypes = []
+ elif not isinstance(segtypes, list):
+ segtypes = [segtypes]
+ return segtypes
+
def udev_device_dm_subsystem_match(info, subsystem):
""" Return True if the device matches a given device-mapper subsystem. """
uuid = info.get("DM_UUID", "")
--
1.8.1.4
More information about the anaconda-patches
mailing list