From b633b22f593adfce2fa3b02c72f928fff46a0651 Mon Sep 17 00:00:00 2001 From: brent s Date: Thu, 7 Nov 2019 19:42:43 -0500 Subject: [PATCH] gi lvm done; added better size support and ability to specify PE size --- aif.xsd | 25 +++++++++++++++++++++++-- aif/disk/lvm.py | 39 +++++++++++++++++++++++++++++++++++++-- aif/disk/lvm_fallback.py | 8 ++++++-- docs/MANUAL.adoc | 6 ++++++ examples/aif.xml | 9 ++++++--- 5 files changed, 78 insertions(+), 9 deletions(-) diff --git a/aif.xsd b/aif.xsd index d0cc6ea..bf53e8d 100644 --- a/aif.xsd +++ b/aif.xsd @@ -30,6 +30,25 @@ + + + + + + + + + + + + + + + + + + @@ -492,7 +511,8 @@ - + - @@ -514,6 +534,7 @@ + diff --git a/aif/disk/lvm.py b/aif/disk/lvm.py index 9c76ea8..b1c8faf 100644 --- a/aif/disk/lvm.py +++ b/aif/disk/lvm.py @@ -1,6 +1,7 @@ import uuid ## from . import _common +import aif.utils import aif.disk.block as block import aif.disk.luks as luks import aif.disk.mdadm as mdadm @@ -105,6 +106,14 @@ class VG(object): self.xml = vg_xml self.id = self.xml.attrib('id') self.name = self.xml.attrib('name') + self.pe_size = self.xml.attrib.get('extentSize', 0) + if self.pe_size: + x = dict(zip(('from_bgn', 'size', 'type'), + aif.utils.convertSizeUnit(self.pe_size))) + if x['type']: + self.pe_size = aif.utils.size.convertStorage(self.pe_size, + x['type'], + target = 'B') self.lvs = [] self.pvs = [] # self.tags = [] @@ -133,7 +142,7 @@ class VG(object): # opts.append(_BlockDev.ExtraArg.new('--addtag', t)) _BlockDev.lvm.vgcreate(self.name, [p.devpath for p in self.pvs], - 0, + self.pe_size, opts) for p in self.pvs: p._parseMeta() @@ -190,7 +199,6 @@ class LV(object): self.xml = lv_xml self.id = self.xml.attrib('id') self.name = self.xml.attrib('name') - self.size = self.xml.attrib('size') # Convert to bytes. Can get max from _BlockDev.lvm.vginfo().free TODO self.vg = vgobj self.pvs = [] if not isinstance(self.vg, VG): @@ -211,6 +219,33 @@ class LV(object): self.pvs.append(_indexed_pvs[pv_id]) if not self.pvs: # We get all in the VG instead since none were explicitly assigned self.pvs = self.vg.pvs + # Size processing. We have to do this after indexing PVs. + # TODO: allow specify PE size (t_lvsize? as well?)? + # If not x['type'], assume *extents*, not sectors + self.size = self.xml.attrib('size') # Convert to bytes. Can get max from _BlockDev.lvm.vginfo().free TODO + x = dict(zip(('from_bgn', 'size', 'type'), + aif.utils.convertSizeUnit(self.xml.attrib['size']))) + # self.size is bytes + self.size = x['size'] + _extents = {'size': self.vg.info['extent_size'], + 'total': 0} # We can't use self.vg.info['extent_count'] because selective PVs. + _sizes = {'total': 0, + 'free': 0} + _vg_pe = self.vg.info['extent_size'] + for pv in self.pvs: + _sizes['total'] += pv.info['pv_size'] + _sizes['free'] += pv.info['pv_free'] + _extents['total'] += int(pv.info['pv_size'] / _extents['size']) + if x['type'] == '%': + self.size = int(_sizes['total'] * (0.01 * self.size)) + elif x['type'] is None: + self.size = int(self.size * _extents['size']) + else: + self.size = int(aif.utils.size.convertStorage(x['size'], + x['type'], + target = 'B')) + if self.size >= _sizes['total']: + self.size = 0 return() def create(self): diff --git a/aif/disk/lvm_fallback.py b/aif/disk/lvm_fallback.py index 71e1447..4cb19f6 100644 --- a/aif/disk/lvm_fallback.py +++ b/aif/disk/lvm_fallback.py @@ -20,9 +20,13 @@ class PV(object): 'aif.disk.block.Partition, ' 'aif.disk.luks.LUKS, or' 'aif.disk.mdadm.Array')) - # TODO self.devpath = self.device.devpath - pass + self.is_pooled = False + self.meta = None + self._parseMeta() + + def _parseMeta(self): + pass # TODO class LV(object): diff --git a/docs/MANUAL.adoc b/docs/MANUAL.adoc index ff9f125..f7d85d5 100644 --- a/docs/MANUAL.adoc +++ b/docs/MANUAL.adoc @@ -558,6 +558,12 @@ TL;DR: "It's the safest way to make sure your disk doesn't suffer massive degrad === "Why isn't my last GPT partition extending to the last sector?" See above. +=== "Why do partitions take `start`/`stop` attributes but LVs take `size`?" +Using `start`/`stop` attributes makes sense for disk partitions because they operate on actual geometry (positions on-disk); that is, this lets you create a "gap" between partitions on the disk which can be helpful if you want to do any modifications to the partition table afterwards (this is also why partitions are processed in the order they're specified). + +LVM (LVs, in particular), however, aren't consecutive. There *is* no concept of a "start" and "stop" for an LV; LVM uses chunks called "(physical) extents" rather than sectors, and VGs don't have geometry since they're essentially a pool of blocks. This is also why the modifiers like `-` and `+` aren't allowed for LV sizes - they're position-based. + + == Bug Reports/Feature Requests NOTE: It is possible to submit a bug or feature request without registering in my bugtracker. One of my pet peeves is needing to create an account/register on a bugtracker simply to report a bug! The following links only require an email address to file a bug (which is necessary in case I need any further clarification from you or to keep you updated on the status of the bug/feature request -- so please be sure to use a valid email address). diff --git a/examples/aif.xml b/examples/aif.xml index 87e2fb4..bf518f3 100644 --- a/examples/aif.xml +++ b/examples/aif.xml @@ -56,15 +56,18 @@ - + - - + +