I may have to clone some bugs for f20 if process requires a bug. Patches 3 and 5 could be left out of f20 if we're in lockdown mode already, but they're both low-risk and improve the code we're maintaining so I think deferring them would be a mistake.
--- blivet/devicefactory.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py index 627819f..924dab6 100644 --- a/blivet/devicefactory.py +++ b/blivet/devicefactory.py @@ -647,8 +647,11 @@ class DeviceFactory(object): parent_container.addMember(self.device)
def _set_name(self): - if self.device_name is None: - return + if not self.device_name: + self.device_name = self.storage.suggestDeviceName( + parent=self.container, + swap=(self.fstype == "swap"), + mountpoint=self.mountpoint)
# TODO: write a StorageDevice.name setter safe_new_name = self.storage.safeDeviceName(self.device_name) @@ -1204,8 +1207,11 @@ class LVMFactory(DeviceFactory): return self.storage.newLV(*args, **kwargs)
def _set_name(self): - if self.device_name is None: - return + if not self.device_name: + self.device_name = self.storage.suggestDeviceName( + parent=self.container, + swap=(self.fstype == "swap"), + mountpoint=self.mountpoint)
# TODO: write a StorageDevice.name setter lvname = "%s-%s" % (self.container.name, self.device_name) @@ -1629,7 +1635,4 @@ class BTRFSFactory(DeviceFactory):
def _set_name(self): super(BTRFSFactory, self)._set_name() - if self.device_name is None: - return - self.device.format.options = "subvol=" + self.device.name
Instead of trying to figure out how to sort the lvs by attr (probably not possible) just allow for adding building-block volumes on demand. --- blivet/devices.py | 12 ++++- blivet/devicetree.py | 136 +++++++++++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 60 deletions(-)
diff --git a/blivet/devices.py b/blivet/devices.py index 6650086..d620eaf 100644 --- a/blivet/devices.py +++ b/blivet/devices.py @@ -2104,6 +2104,9 @@ class LVMVolumeGroupDevice(DMDevice): self.reserved_percent = 0 self.reserved_space = 0
+ # this will have to be covered by the 20% pad for non-existent pools + self.poolMetaData = 0 + # circular references, here I come self._lvs = []
@@ -2319,6 +2322,9 @@ class LVMVolumeGroupDevice(DMDevice):
self._lvs.remove(lv)
+ if self.poolMetaData and not self.thinpools: + self.poolMetaData = 0 + def _addPV(self, pv): """ Add a PV to this VG. """ if pv in self.pvs: @@ -2421,6 +2427,7 @@ class LVMVolumeGroupDevice(DMDevice): log.debug("%s size is %dMB" % (self.name, self.size)) used = sum(lv.vgSpaceUsed for lv in self.lvs) + self.snapshotSpace used += self.reservedSpace + used += self.poolMetaData free = self.size - used log.debug("vg %s has %dMB free" % (self.name, free)) return free @@ -2788,7 +2795,7 @@ class LVMThinPoolDevice(LVMLogicalVolumeDevice): def __init__(self, name, parents=None, size=None, uuid=None, format=None, exists=False, sysfsPath='', grow=None, maxsize=None, percent=None, - metadatasize=None, chunksize=None): + metadatasize=None, chunksize=None, segType=None): """ Create a LVMLogicalVolumeDevice instance.
Arguments: @@ -2826,7 +2833,8 @@ class LVMThinPoolDevice(LVMLogicalVolumeDevice): format=format, exists=exists, sysfsPath=sysfsPath, grow=grow, maxsize=maxsize, - percent=percent) + percent=percent, + segType=segType)
self.metaDataSize = metadatasize or 0 self.chunkSize = chunksize or 0 diff --git a/blivet/devicetree.py b/blivet/devicetree.py index 7bb746f..de19f6e 100644 --- a/blivet/devicetree.py +++ b/blivet/devicetree.py @@ -1180,26 +1180,22 @@ class DeviceTree(object): % device.format.mapName)
def handleVgLvs(self, vg_device): - """ Handle setup of the LV's in the vg_device - return True if an LV was setup - return False if there was an error, or no more LV's to setup - """ - ret = False + """ Handle setup of the LV's in the vg_device. """ 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 + lv_attrs = vg_device.lv_attr lv_types = vg_device.lv_types
if not vg_device.complete: log.warning("Skipping LVs for incomplete VG %s" % vg_name) - return False + return
if not lv_names: log.debug("no LVs listed for VG %s" % vg_name) - return False + return
def lv_attr_cmp(a, b): """ Sort so that mirror images come first and snapshots last. """ @@ -1220,85 +1216,96 @@ class DeviceTree(object): else: return 0
- # make a list of indices with mirror volumes up front and snapshots at - # the end - indices = range(len(lv_names)) - indices.sort(key=lambda i: lv_attr[i], cmp=lv_attr_cmp) - raid = {} - for index in indices: + def addLV(lv_name, lv_uuid, lv_attr, lv_size, lv_type): lv_class = LVMLogicalVolumeDevice - lv_name = lv_names[index] lv_parents = [vg_device] name = "%s-%s" % (vg_name, lv_name) - if lv_attr[index][0] in 'Ss': + + if self.getDeviceByName(name): + # some lvs may have been added on demand below + log.debug("already added %s" % name) + return + + if lv_attr[0] in 'Ss': log.info("found lvm snapshot volume '%s'" % name) origin_name = devicelibs.lvm.lvorigin(vg_name, lv_name) if not origin_name: log.error("lvm snapshot '%s-%s' has unknown origin" % (vg_name, lv_name)) - continue + return
- origin = self.getDeviceByName("%s-%s" % (vg_name, - origin_name)) + origin_device_name = "%s-%s" % (vg_name, origin_name) + origin = self.getDeviceByName(origin_device_name) if not origin: if origin_name.endswith("_vorigin]"): log.info("snapshot volume '%s' has vorigin" % name) - vg_device.voriginSnapshots[lv_name] = lv_sizes[index] + vg_device.voriginSnapshots[lv_name] = lv_size + return else: - log.warning("snapshot lv '%s' origin lv '%s-%s' " - "not found" % (name, - vg_name, origin_name)) - continue + oidx = lv_names.index(origin_name) + if oidx: + addLV(*lv_data[oidx]) + origin = self.getDeviceByName(origin_device_name) + + if origin is None: + log.warning("snapshot lv '%s' origin lv '%s' not " + "found" % (name, origin_device_name)) + return
log.debug("adding %dMB to %s snapshot total" % (lv_sizes[index], origin.name)) - origin.snapshotSpace += lv_sizes[index] - continue - elif lv_attr[index][0] == 'v': + origin.snapshotSpace += lv_size + return + elif lv_attr[0] == 'v': # skip vorigins - continue - elif lv_attr[index][0] in 'Ii': + return + elif lv_attr[0] in 'Ii': # mirror image - lv_name = re.sub(r'_[rm]image.+', '', lv_name[1:-1]) - name = "%s-%s" % (vg_name, lv_name) - if name not in raid: - raid[name] = {"copies": 0, "log": 0, "meta": 0} - + rname = re.sub(r'_[rm]image.+', '', lv_name[1:-1]) + name = "%s-%s" % (vg_name, rname) raid[name]["copies"] += 1 - continue - elif lv_attr[index][0] == 'e': + return + elif lv_attr[0] == 'e': + if lv_name.endswith("_pmspare]"): + # spare metadata area for any thin pool that needs repair + vg_device.poolMetaData += lv_size + return + # 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': + raid[name]["meta"] += lv_size + return + elif lv_attr[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: - raid[name] = {"stripes": 0, "log": 0, "meta": 0} - - raid[name]["log"] = lv_sizes[index] - continue - elif lv_attr[index][0] == 't': + rname = re.sub(r'_mlog.*', '', lv_name[1:-1]) + name = "%s-%s" % (vg_name, rname) + raid[name]["log"] = lv_size + return + elif lv_attr[0] == 't': # thin pool lv_class = LVMThinPoolDevice - elif lv_attr[index][0] == 'V': + elif lv_attr[0] == 'V': # thin volume pool_name = devicelibs.lvm.thinlvpoolname(vg_name, lv_name) - pool_device = self.getDeviceByName("%s-%s" % (vg_name, - pool_name)) + pool_device_name = "%s-%s" % (vg_name, pool_name) + pool_device = self.getDeviceByName(pool_device_name) + if pool_device is None: + pidx = lv_names.index(pool_name) + if pidx: + addLV(*lv_data[pidx]) + pool_device = self.getDeviceByName(pool_device_name) + if pool_device is None: raise DeviceTreeError("failed to look up thin pool") + lv_class = LVMThinLogicalVolumeDevice lv_parents = [pool_device] + elif lv_attr[0] not in '-mMrR': + return
- lv_dev = self.getDeviceByUuid(lv_uuids[index]) + lv_dev = self.getDeviceByUuid(lv_uuid) if lv_dev is None: - lv_uuid = lv_uuids[index] - lv_size = lv_sizes[index] - lv_type = lv_types[index] lv_device = lv_class(lv_name, parents=lv_parents, uuid=lv_uuid, size=lv_size,segType=lv_type, exists=True) @@ -1311,15 +1318,30 @@ class DeviceTree(object): lv_info = udev_get_block_device(lv_device.sysfsPath) if not lv_info: log.error("failed to get udev data for lv %s" % lv_device.name) - continue + return
# do format handling now self.addUdevDevice(lv_info)
- ret = True + # make a list of indices with mirror volumes up front and snapshots at + # the end + indices = range(len(lv_names)) + indices.sort(key=lambda i: lv_attrs[i], cmp=lv_attr_cmp) + lv_real_names = [n.replace("[", "").replace("]", "") for n in lv_names] + raid = dict([("%s-%s" % (vg_device.name, + n.replace("[", "").replace("]", "")), + {"copies": 0, "log": 0, "meta": 0}) + for n in lv_names]) + lv_data = zip(lv_names, lv_uuids, lv_attrs, lv_sizes, lv_types) + for i in range(len(lv_data)): + addLV(*lv_data[i])
for name, data in raid.items(): lv_dev = self.getDeviceByName(name) + if not lv_dev: + # hidden lv, eg: pool00_tdata + continue + lv_dev.copies = data["copies"] lv_dev.metaDataSize = data["meta"] lv_dev.logSize = data["log"] @@ -1328,8 +1350,6 @@ class DeviceTree(object): % (lv_dev.name, lv_dev.copies, lv_dev.metaDataSize, lv_dev.logSize, lv_dev.vgSpaceUsed))
- return ret - def handleUdevLVMPVFormat(self, info, device): log_method_call(self, name=device.name, type=device.format.type) # lookup/create the VG and LVs
--- blivet/__init__.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/blivet/__init__.py b/blivet/__init__.py index 8f6e82a..d8c5c6f 100644 --- a/blivet/__init__.py +++ b/blivet/__init__.py @@ -53,6 +53,7 @@ import errno import sys import statvfs import copy +import tempfile
try: import nss.nss @@ -168,12 +169,7 @@ def turnOnFilesystems(storage, mountOnly=False): try: storage.doIt() except FSResizeError as e: - if os.path.exists("/tmp/resize.out"): - details = open("/tmp/resize.out", "r").read() - else: - details = e.args[1] - - if errorHandler.cb(e, e.args[0], details=details) == ERROR_RAISE: + if errorHandler.cb(e, e.args[0], details=e.args[1]) == ERROR_RAISE: raise except Exception as e: raise @@ -294,7 +290,7 @@ class Blivet(object): self.dasd = dasd.DASD()
self._nextID = 0 - self._dumpFile = "/tmp/storage.state" + self._dumpFile = "%s/storage.state" % tempfile.gettempdir()
# these will both be empty until our reset method gets called self.devicetree = DeviceTree(conf=self.config,
--- blivet/formats/fs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py index 13896c9..f9b54b1 100644 --- a/blivet/formats/fs.py +++ b/blivet/formats/fs.py @@ -165,7 +165,7 @@ class FS(DeviceFormat):
self._targetSize = self._size
- if self.supported: + if self.supported and flags.installer_mode: self.loadModule()
def __repr__(self):
--- blivet/util.py | 1 + 1 file changed, 1 insertion(+)
diff --git a/blivet/util.py b/blivet/util.py index 9d038cd..a9efa34 100644 --- a/blivet/util.py +++ b/blivet/util.py @@ -36,6 +36,7 @@ def _run_program(argv, root='/', stdin=None, env_prune=None): stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + close_fds=True, preexec_fn=chroot, cwd=root, env=env)
out = proc.communicate()[0]
On Mon, Oct 14, 2013 at 12:44:18PM -0500, David Lehman wrote:
I may have to clone some bugs for f20 if process requires a bug. Patches 3 and 5 could be left out of f20 if we're in lockdown mode already, but they're both low-risk and improve the code we're maintaining so I think deferring them would be a mistake.
These all look ok, at least I think they do. #2 is fairly big :)
anaconda-patches@lists.fedorahosted.org