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 @@
-
+
-
-
+
+