From: Vratislav Podzimek <vpodzime(a)redhat.com>
DM maps cannot be removed while they are in use so in order to make them
removable, we need to teardown all devices "built" on top of them first. Since
we don't support using disk images together with real disks we can safely just
tear all devices down. This makes our examples (and possibly some tests) better
clean after themselves.
---
blivet/devicetree.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index fe10aa5..953d977 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -1048,6 +1048,9 @@ def setup_disk_images(self):
def teardown_disk_images(self):
""" Tear down any disk image stacks. """
+ # teardown all devices first so that there's nothing active running on
+ # top of disk images when we try to tear those down
+ self.teardown_all()
self._populator.teardown_disk_images()
@property
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/1111ba89d6f11f75c3c6b545955df0…
From: Vratislav Podzimek <vpodzime(a)redhat.com>
It's just more common these days and the definition is easier to find and
recognize in the sources.
---
blivet/devices/device.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/blivet/devices/device.py b/blivet/devices/device.py
index 48ea554..62637aa 100644
--- a/blivet/devices/device.py
+++ b/blivet/devices/device.py
@@ -148,18 +148,18 @@ def _init_parent_list(self):
for parent in list(self._parents):
self._parents.remove(parent)
- def _set_parent_list(self, parents):
+ @property
+ def parents(self):
+ """ Devices upon which this device is built """
+ return self._parents
+
+ @parents.setter
+ def parents(self, parents):
""" Set this instance's parent list. """
self._init_parent_list()
for parent in parents:
self._parents.append(parent)
- def _get_parent_list(self):
- return self._parents
-
- parents = property(_get_parent_list, _set_parent_list,
- doc="devices upon which this device is built")
-
@property
def dict(self):
d = {"type": self.type, "name": self.name,
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/24799edea1a46b6ded5cc0ead13e64…
From: Vratislav Podzimek <vpodzime(a)redhat.com>
This really only takes care about passing the type down to libblockdev and thus
lvcreate. We need to a lot more to actually fully support various types of LVs.
---
blivet/devices/lvm.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index 159e3ef..de40fd6 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -841,7 +841,9 @@ def _create(self):
# TODO: specify sizes together with PVs once LVM and libblockdev support it
pvs = [spec.pv.path for spec in self._pv_specs]
pvs = pvs or None
- blockdev.lvm.lvcreate(self.vg.name, self._name, self.size, pv_list=pvs)
+
+ blockdev.lvm.lvcreate(self.vg.name, self._name, self.size,
+ type=self.seg_type, pv_list=pvs)
else:
mode = blockdev.lvm.cache_get_mode_from_str(self.cache.mode)
# prepare the list of fast PV devices
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/d96d2a807ae4f871813ee38886bfb5…
This adds an elementary support of non-linear LVs to Blivet. The first patch is unrelated, but also useful. Tests will follow later.
--
To view this pull request on github, visit https://github.com/rhinstaller/blivet/pull/286
From: Vratislav Podzimek <vpodzime(a)redhat.com>
This allows for more precise configuration of how the LVM setup should look
like. We already have some rudimentary support for specifying PVs for caches
which is a must, but it's useful for all LVs in general.
Thanks dlehman(a)redhat.com for pieces of code and ideas for this patch!
---
blivet/devices/lvm.py | 48 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 39 insertions(+), 9 deletions(-)
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index 350e423..159e3ef 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -27,6 +27,7 @@
import re
import os
import time
+from collections import namedtuple
import gi
gi.require_version("BlockDev", "1.0")
@@ -72,6 +73,10 @@ def get_internal_lv_class(lv_attr):
return None
+LVPVSpec = namedtuple("LVPVSpec", ["pv", "size"])
+""" A namedtuple class for specifying how much space on a PV should be allocated for some LV """
+
+
class LVMVolumeGroupDevice(ContainerDevice):
""" An LVM Volume Group """
@@ -512,7 +517,7 @@ class LVMLogicalVolumeDevice(DMDevice):
def __init__(self, name, parents=None, size=None, uuid=None, seg_type=None,
fmt=None, exists=False, sysfs_path='', grow=None, maxsize=None,
- percent=None, cache_request=None):
+ percent=None, cache_request=None, pvs=None):
"""
:param name: the device name (generally a device node's basename)
:type name: str
@@ -544,6 +549,8 @@ def __init__(self, name, parents=None, size=None, uuid=None, seg_type=None,
:type percent: int
:keyword cache_request: parameters of requested cache (if any)
:type cache_request: :class:`~.devices.lvm.LVMCacheRequest`
+ :keyword pvs: list of PVs to allocate extents from (size could be specified for each PV)
+ :type pvs: list of :class:`~.devices.StorageDevice` or :class:`LVPVSpec` objects (tuples)
"""
@@ -581,6 +588,21 @@ def __init__(self, name, parents=None, size=None, uuid=None, seg_type=None,
self._cache = LVMCache(self, size=cache_request.size, exists=False,
fast_pvs=cache_request.fast_devs, mode=cache_request.mode)
+ self._pv_specs = []
+ for pv_spec in pvs:
+ if isinstance(pv_spec, LVPVSpec):
+ self._pv_specs.append(pv_spec)
+ elif isinstance(pv_spec, StorageDevice):
+ self._pv_specs.append(LVPVSpec(pv_spec, Size(0)))
+ else:
+ raise ValueError("Invalid PV spec '%s' for the '%s' LV" % (pv_spec, self.name))
+ # Make sure any destination PVs are actually PVs in this VG
+ if not set(spec.pv for spec in self._pv_specs).issubset(set(self.vg.parents)):
+ missing = [r.name for r in
+ set(spec.pv for spec in self._pv_specs).difference(set(self.vg.parents))]
+ msg = "invalid destination PV(s) %s for LV %s" % (missing, self.name)
+ raise ValueError(msg)
+
def _check_parents(self):
"""Check that this device has parents as expected"""
@@ -816,7 +838,10 @@ def _create(self):
# should we use --zero for safety's sake?
if not self.cache:
# just a plain LV
- blockdev.lvm.lvcreate(self.vg.name, self._name, self.size)
+ # TODO: specify sizes together with PVs once LVM and libblockdev support it
+ pvs = [spec.pv.path for spec in self._pv_specs]
+ pvs = pvs or None
+ blockdev.lvm.lvcreate(self.vg.name, self._name, self.size, pv_list=pvs)
else:
mode = blockdev.lvm.cache_get_mode_from_str(self.cache.mode)
# prepare the list of fast PV devices
@@ -828,13 +853,17 @@ def _create(self):
else:
fast_pvs.append(pv_name)
- # get the list of all fast PV devices used in the VG so that we can
- # consider the rest to be slow PVs and generate a list of them
- all_fast_pvs_names = set()
- for lv in self.vg.lvs:
- if lv.cached and lv.cache.fast_pvs:
- all_fast_pvs_names |= set(pv.name for pv in lv.cache.fast_pvs)
- slow_pvs = [pv.path for pv in self.vg.pvs if pv.name not in all_fast_pvs_names]
+ if self._pv_specs:
+ # (slow) PVs specified for this LV
+ slow_pvs = [spec.pv.path for spec in self._pv_specs]
+ else:
+ # get the list of all fast PV devices used in the VG so that we can
+ # consider the rest to be slow PVs and generate a list of them
+ all_fast_pvs_names = set()
+ for lv in self.vg.lvs:
+ if lv.cached and lv.cache.fast_pvs:
+ all_fast_pvs_names |= set(pv.name for pv in lv.cache.fast_pvs)
+ slow_pvs = [pv.path for pv in self.vg.pvs if pv.name not in all_fast_pvs_names]
# VG name, LV name, data size, cache size, metadata size, mode, flags, slow PVs, fast PVs
# XXX: we need to pass slow_pvs+fast_pvs as slow PVs because parts
@@ -1573,6 +1602,7 @@ def _create(self):
else:
profile_name = None
# TODO: chunk size, data/metadata split --> profile
+ # TODO: allow for specification of PVs
blockdev.lvm.thpoolcreate(self.vg.name, self.lvname, self.size,
md_size=self.metadata_size,
chunk_size=self.chunk_size,
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/6e2a6875f300ba70d84cc400323abb…
Trying again with a subtree, suggested by @M4rtinK, which seems a lot less annoying. Instead of a remote ref, translation-canary gets merged into this project in a way that can it can be managed as a separate entity.
--
To view this pull request on github, visit https://github.com/rhinstaller/anaconda/pull/463