[PATCH 10/20] Use BlockDev's LVM plugin instead of devicelibs/lvm.py
vpodzime
installerbot-noreply at redhat.com
Fri Feb 27 15:31:52 UTC 2015
From: Vratislav Podzimek <vpodzime at redhat.com>
Except for a few things BlockDev doesn't provide.
---
blivet/devicefactory.py | 25 ++-
blivet/devicelibs/lvm.py | 506 +----------------------------------------------
blivet/devices/lvm.py | 72 +++----
blivet/devicetree.py | 89 ++++-----
blivet/errors.py | 3 -
blivet/formats/lvmpv.py | 19 +-
blivet/partitioning.py | 7 +-
7 files changed, 109 insertions(+), 612 deletions(-)
diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py
index bf41d55..e78159a 100644
--- a/blivet/devicefactory.py
+++ b/blivet/devicefactory.py
@@ -1143,7 +1143,8 @@ def _handle_no_size(self):
super(LVMFactory, self)._handle_no_size()
def _get_device_space(self):
- return lvm.get_pv_space(self.size, len(self._get_member_devices()))
+ # XXX: should respect the real extent size
+ return blockdev.lvm_get_lv_physical_size(self.size, lvm.LVM_PE_SIZE)
def _get_device_size(self):
size = self.size
@@ -1187,7 +1188,8 @@ def _get_total_space(self):
log.debug("size bumped to %s to include free disk space", size)
else:
# container_size is a request for a fixed size for the container
- size += lvm.get_pv_space(self.container_size, len(self.disks))
+ # XXX: should respect the real extent size
+ size += blockdev.lvm_get_lv_physical_size(self.container_size, lvm.LVM_PE_SIZE)
# this does not apply if a specific container size was requested
if self.container_size in [SIZE_POLICY_AUTO, SIZE_POLICY_MAX]:
@@ -1197,8 +1199,8 @@ def _get_total_space(self):
# The member count here uses the container's current member set
# since that's the basis for the current device's disk space
# usage.
- size -= lvm.get_pv_space(self.device.size,
- len(self.container.parents))
+ # XXX: should respect the real extent size
+ size -= blockdev.lvm_get_lv_physical_size(self.device.size, lvm.LVM_PE_SIZE)
log.debug("size cut to %s to omit old device space", size)
if self.container_raid_level:
@@ -1389,7 +1391,7 @@ def _get_device_space(self):
"""
space = super(LVMThinPFactory, self)._get_device_space()
log.debug("calculated total disk space prior to padding: %s", space)
- space += lvm.get_pool_padding(space, pesize=self._pesize)
+ space += Size(blockdev.lvm_get_thpool_padding(space, self._pesize))
log.debug("total disk space needed: %s", space)
return space
@@ -1407,8 +1409,7 @@ def _get_total_space(self):
size -= self.pool.freeSpace
log.debug("size cut to %s to omit pool free space", size)
- pad = lvm.get_pool_padding(self.pool.freeSpace,
- pesize=self._pesize)
+ pad = Size(blockdev.lvm_get_thpool_padding(self.pool.freeSpace, self._pesize))
size -= pad
log.debug("size cut to %s to omit pool padding from free "
"space", size)
@@ -1419,8 +1420,7 @@ def _get_total_space(self):
# The member count here uses the container's current member set
# since that's the basis for the current device's disk space
# usage.
- pad = lvm.get_pool_padding(self.device.size,
- pesize=self._pesize)
+ pad = Size(blockdev.lvm_get_thpool_padding(self.device.size, self._pesize))
log.debug("old device size: %s ; old pad: %s", self.device.size, pad)
size -= pad
log.debug("size cut to %s to omit old device padding", size)
@@ -1484,8 +1484,7 @@ def _get_pool_size(self):
size -= self.device.poolSpaceUsed # don't count our device
# increase vg free space by the size of the current pool's pad
- pad = lvm.get_pool_padding(self.pool.size,
- pesize=self._pesize)
+ pad = Size(blockdev.lvm_get_thpool_padding(self.pool.size, self._pesize))
log.debug("increasing free by current pool pad size (%s)", pad)
free += pad
@@ -1493,11 +1492,11 @@ def _get_pool_size(self):
free = self.container.align(free + self.container.freeSpace)
size = self.container.align(size, roundup=True)
- pad = lvm.get_pool_padding(size, pesize=self._pesize)
+ pad = Size(blockdev.lvm_get_thpool_padding(size, self._pesize))
log.debug("size is %s ; pad is %s ; free is %s", size, pad, free)
if free < (size + pad):
- pad = int(lvm.get_pool_padding(free, pesize=self._pesize, reverse=True))
+ pad = Size(blockdev.lvm_get_thpool_padding(free, self._pesize, included=True))
free = self.container.align(free - pad) # round down
log.info("adjusting pool size from %s to %s so it fits "
"in container %s", size, free, self.container.name)
diff --git a/blivet/devicelibs/lvm.py b/blivet/devicelibs/lvm.py
index 290e64d..1fd22de 100644
--- a/blivet/devicelibs/lvm.py
+++ b/blivet/devicelibs/lvm.py
@@ -20,18 +20,14 @@
# Author(s): Dave Lehman <dlehman at redhat.com>
#
-from decimal import Decimal
from collections import namedtuple
import logging
log = logging.getLogger("blivet")
from . import raid
-from ..size import Size, KiB, MiB
-from .. import util
-from .. import arch
-from ..errors import LVMError
-from ..i18n import _, N_
+from ..size import Size
+from ..i18n import N_
from ..flags import flags
# some of lvm's defaults that we have no way to ask it for
@@ -112,501 +108,3 @@ def lvm_cc_resetFilter():
config_args_data["filterRejects"] = []
config_args_data["filterAccepts"] = []
# End config_args handling code.
-
-def getPossiblePhysicalExtents():
- """ Returns a list of possible values for physical extent of a volume group.
-
- :returns: list of possible extent sizes (:class:`~.size.Size`)
- :rtype: list
- """
- return [Size(1024 * (2 ** n)) for n in range(25)]
-
-def getMaxLVSize():
- """ Return the maximum size of a logical volume. """
- if arch.getArch() in ("x86_64", "ppc64", "ppc64le", "alpha", "ia64", "s390"): #64bit architectures
- return Size("8 EiB")
- else:
- return Size("16 TiB")
-
-def clampSize(size, pesize, roundup=None):
- delta = size % pesize
- if not delta:
- return size
-
- if roundup:
- clamped = size + (pesize - delta)
- else:
- clamped = size - delta
-
- return clamped
-
-def get_pv_space(size, disks, pesize=LVM_PE_SIZE):
- """ Given specs for an LV, return total PV space required. """
- # XXX default extent size should be something we can ask of lvm
- # TODO: handle striped and mirrored
- # this is adding one extent for the lv's metadata
- # pylint: disable=unused-argument
- if size == Size(0):
- return Size(0)
-
- space = clampSize(size, pesize, roundup=True) + pesize
- return space
-
-def get_pool_padding(size, pesize=LVM_PE_SIZE, reverse=False):
- """ Return the size of the pad required for a pool with the given specs.
-
- reverse means the pad is already included in the specified size and we
- should calculate how much of the total is the pad
- """
- if not reverse:
- multiplier = Decimal('0.2')
- else:
- multiplier = Decimal('1.0') / Decimal('6')
-
- pad = min(clampSize(size * multiplier, pesize, roundup=True),
- clampSize(LVM_THINP_MAX_METADATA_SIZE, pesize, roundup=True))
-
- return pad
-
-def is_valid_thin_pool_metadata_size(size):
- """ Return True if size is a valid thin pool metadata vol size.
-
- :param size: metadata vol size to validate
- :type size: :class:`~.size.Size`
- :returns: whether the size is valid
- :rtype: bool
- """
- return (LVM_THINP_MIN_METADATA_SIZE <= size <= LVM_THINP_MAX_METADATA_SIZE)
-
-# To support discard, chunk size must be a power of two. Otherwise it must be a
-# multiple of 64 KiB.
-def is_valid_thin_pool_chunk_size(size, discard=False):
- """ Return True if size is a valid thin pool chunk size.
-
- :param size: chunk size to validate
- :type size: :class:`~.size.Size`
- :keyword discard: whether discard support is required (default: False)
- :type discard: bool
- :returns: whether the size is valid
- :rtype: bool
- """
- if not LVM_THINP_MIN_CHUNK_SIZE <= size <= LVM_THINP_MAX_CHUNK_SIZE:
- return False
-
- if discard:
- return util.power_of_two(int(size))
- else:
- return (size % LVM_THINP_MIN_CHUNK_SIZE == Size(0))
-
-def strip_lvm_warnings(buf):
- """ Strip out lvm warning lines
-
- :param str buf: A string returned from lvm
- :returns: A list of strings with warning lines stripped
- :rtype: list of str
- """
- return [l for l in buf.splitlines() if l and not l.lstrip().startswith("WARNING:")]
-
-def lvm(args, capture=False, ignore_errors=False):
- """ Runs lvm with specified arguments.
-
- :param bool capture: if True, return the output of the command.
- :param bool ignore_errors: if True, do not raise LVMError on failure
- :returns: list of strings from the output of the command or None
- :rtype: list or NoneType
- :raises: LVMError if command fails
- """
- argv = ["lvm"] + args + _getConfigArgs(args)
- (ret, out) = util.run_program_and_capture_output(argv)
- if ret and not ignore_errors:
- raise LVMError("running "+ " ".join(argv) + " failed")
- if capture:
- return strip_lvm_warnings(out)
-
-def pvcreate(device, data_alignment=None):
- args = ["pvcreate"]
- if data_alignment is not None:
- args.extend(["--dataalignment", "%dk" % data_alignment.convertTo(KiB)])
- args.append(device)
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("pvcreate failed for %s: %s" % (device, msg))
-
-def pvresize(device, size):
- args = ["pvresize",
- "--setphysicalvolumesize", ("%dm" % size.convertTo(MiB)),
- device]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("pvresize failed for %s: %s" % (device, msg))
-
-def pvremove(device):
- args = ["pvremove", "--force", "--force", "--yes", device]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("pvremove failed for %s: %s" % (device, msg))
-
-def pvscan(device):
- args = ["pvscan", "--cache", device]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("pvscan failed for %s: %s" % (device, msg))
-
-def pvmove(source, dest=None):
- """ Move physical extents from one PV to another.
-
- :param str source: pv device path to move extents off of
- :keyword str dest: pv device path to move the extents onto
- """
- args = ["pvmove", source]
- if dest:
- args.append(dest)
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("pvmove failed for %s->%s: %s" % (source, dest, msg))
-
-def parse_lvm_vars(line):
- info = {}
- for var in line.split():
- (name, equals, value) = var.partition("=")
- if not equals:
- continue
-
- if "," in value:
- val = value.strip().split(",")
- else:
- val = value.strip()
-
- info[name] = val
-
- return info
-
-def pvinfo(device=None):
- """ Return a dict with information about LVM PVs.
-
- :keyword str device: path to PV device node (optional)
- :returns: dict containing PV path keys and udev info dict values
- :rtype: dict
-
- If device is None we let LVM report on all known PVs.
-
- If the PV was created with '--metadacopies 0', lvm will do some
- scanning of devices to determine from their metadata which VG
- this PV belongs to.
-
- pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \
- 'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }'
- """
- args = ["pvs",
- "--unit=k", "--nosuffix", "--nameprefixes",
- "--unquoted", "--noheadings",
- "-opv_name,pv_uuid,pe_start,vg_name,vg_uuid,vg_size,vg_free,"
- "vg_extent_size,vg_extent_count,vg_free_count,pv_count"]
-
- if device:
- args.append(device)
-
- lines = lvm(args, capture=True, ignore_errors=True)
- pvs = {}
- for line in lines:
- info = parse_lvm_vars(line)
- if len(info.keys()) != 11:
- log.warning("ignoring pvs output line: %s", line)
- continue
-
- pvs[info["LVM2_PV_NAME"]] = info
-
- return pvs
-
-def vgcreate(vg_name, pv_list, pe_size):
- argv = ["vgcreate"]
- if pe_size:
- argv.extend(["-s", "%dm" % pe_size.convertTo(MiB)])
- argv.append(vg_name)
- argv.extend(pv_list)
-
- try:
- lvm(argv)
- except LVMError as msg:
- raise LVMError("vgcreate failed for %s: %s" % (vg_name, msg))
-
-def vgremove(vg_name):
- args = ["vgremove", "--force", vg_name]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("vgremove failed for %s: %s" % (vg_name, msg))
-
-def vgactivate(vg_name):
- args = ["vgchange", "-a", "y", vg_name]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("vgactivate failed for %s: %s" % (vg_name, msg))
-
-def vgdeactivate(vg_name):
- args = ["vgchange", "-a", "n", vg_name]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("vgdeactivate failed for %s: %s" % (vg_name, msg))
-
-def vgreduce(vg_name, pv, missing=False):
- """ Remove PVs from a VG.
-
- :param str pv: PV device path to remove
- :keyword bool missing: whether to remove missing PVs
-
- When missing is True any specified PV is ignored and vgreduce is
- instead called with the --removemissing option.
-
- .. note::
-
- This function does not move extents off of the PV before removing
- it from the VG. You must do that first by calling :func:`.pvmove`.
- """
- args = ["vgreduce"]
- if missing:
- args.extend(["--removemissing", "--force", vg_name])
- else:
- args.extend([vg_name, pv])
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("vgreduce failed for %s: %s" % (vg_name, msg))
-
-def vgextend(vg_name, pv):
- """ Add a PV to a VG.
-
- :param str vg_name: the name of the VG
- :param str pv: device path of PV to add
- """
- args = ["vgextend", vg_name, pv]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("vgextend failed for %s: %s" % (vg_name, msg))
-
-def vginfo(vg_name):
- """ Return a dict with information about an LVM VG.
-
- :returns: a udev info dict
- :rtype: dict
- """
- args = ["vgs", "--noheadings", "--nosuffix", "--nameprefixes", "--unquoted",
- "--units", "m",
- "-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count",
- vg_name]
-
- lines = lvm(args, capture=True, ignore_errors=True)
- try:
- info = parse_lvm_vars(lines[0])
- except IndexError:
- info = {}
-
- if len(info.keys()) != 7:
- raise LVMError(_("vginfo failed for %s") % vg_name)
-
- return info
-
-def lvs(vg_name=None):
- """ Return a dict with information about LVM LVs.
-
- :keyword str vgname: name of VG to list LVs from (optional)
- :returns: a dict with LV name keys and udev info dict values
- :rtype: dict
-
- If vg_name is None we let LVM report on all known LVs.
- """
- args = ["lvs",
- "-a", "--unit", "k", "--nosuffix", "--nameprefixes",
- "--unquoted", "--noheadings",
- "-ovg_name,lv_name,lv_uuid,lv_size,lv_attr,segtype"]
- if vg_name:
- args.append(vg_name)
-
- lines = lvm(args, capture=True, ignore_errors=True)
- logvols = {}
- for line in lines:
- info = parse_lvm_vars(line)
- if len(info.keys()) != 6:
- log.debug("ignoring lvs output line: %s", line)
- continue
-
- lv_name = "%s-%s" % (info["LVM2_VG_NAME"], info["LVM2_LV_NAME"])
- logvols[lv_name] = info
-
- return logvols
-
-def lvorigin(vg_name, lv_name):
- args = ["lvs", "--noheadings", "-o", "origin"] + \
- ["%s/%s" % (vg_name, lv_name)]
-
- lines = lvm(args, capture=True, ignore_errors=True)
- try:
- origin = lines[0].strip()
- except IndexError:
- origin = ''
-
- return origin
-
-def lvcreate(vg_name, lv_name, size, pvs=None):
- pvs = pvs or []
-
- args = ["lvcreate"] + \
- ["-L", "%dm" % size.convertTo(MiB)] + \
- ["-n", lv_name] + \
- ["-y"] + \
- [vg_name] + pvs
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
-
-def lvremove(vg_name, lv_name, force=False):
- args = ["lvremove"]
- if force:
- args.extend(["--force", "--yes"])
-
- args += ["%s/%s" % (vg_name, lv_name)]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvremove failed for %s: %s" % (lv_name, msg))
-
-def lvresize(vg_name, lv_name, size):
- args = ["lvresize"] + \
- ["--force", "-L", "%dm" % size.convertTo(MiB)] + \
- ["%s/%s" % (vg_name, lv_name)]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvresize failed for %s: %s" % (lv_name, msg))
-
-def lvactivate(vg_name, lv_name, ignore_skip=False):
- # see if lvchange accepts paths of the form 'mapper/$vg-$lv'
- args = ["lvchange", "-a", "y"]
- if ignore_skip:
- args.append("-K")
-
- args += ["%s/%s" % (vg_name, lv_name)]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvactivate failed for %s: %s" % (lv_name, msg))
-
-def lvdeactivate(vg_name, lv_name):
- args = ["lvchange", "-a", "n"] + \
- ["%s/%s" % (vg_name, lv_name)]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvdeactivate failed for %s: %s" % (lv_name, msg))
-
-def lvsnapshotmerge(vg_name, lv_name):
- """ Merge(/rollback/revert) a snapshot volume into its origin.
-
- .. note::
-
- This is an asynchronous procedure. See lvconvert(8) for details of
- how merge is handled by lvm.
-
- """
- args = ["lvconvert", "--merge", "%s/%s" % (vg_name, lv_name), lv_name]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvsnapshotmerge failed for %s: %s" % (lv_name, msg))
-
-def lvsnapshotcreate(vg_name, snap_name, size, origin_name):
- """
- :param str vg_name: the volume group name
- :param str snap_name: the name of the new snapshot
- :param :class:`~.size.Size` size: the snapshot's size
- :param str origin_name: the name of the origin logical volume
- """
- args = ["lvcreate", "-s", "-L", "%dm" % size.convertTo(MiB),
- "-n", snap_name, "%s/%s" % (vg_name, origin_name)]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvsnapshotcreate failed for %s/%s: %s" % (vg_name, snap_name, msg))
-
-def thinpoolcreate(vg_name, lv_name, size, metadatasize=None, chunksize=None, profile=None):
- args = ["lvcreate", "--thinpool", "%s/%s" % (vg_name, lv_name),
- "--size", "%dm" % size.convertTo(MiB)]
-
- if metadatasize:
- # default unit is MiB
- args += ["--poolmetadatasize", "%d" % metadatasize.convertTo(MiB)]
-
- if chunksize:
- # default unit is KiB
- args += ["--chunksize", "%d" % chunksize.convertTo(KiB)]
-
- if profile:
- args += ["--profile=%s" % profile]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
-
-def thinlvcreate(vg_name, pool_name, lv_name, size):
- args = ["lvcreate", "--thinpool", "%s/%s" % (vg_name, pool_name),
- "--virtualsize", "%dm" % size.convertTo(MiB),
- "-n", lv_name]
-
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
-
-def thinsnapshotcreate(vg_name, snap_name, origin_name, pool_name=None):
- """
- :param str vg_name: the volume group name
- :param str snap_name: the name of the new snapshot
- :param str origin_name: the name of the origin logical volume
- :keyword str pool_name: the name of the pool to create the snapshot in
- """
- args = ["lvcreate", "-s", "-n", snap_name, "%s/%s" % (vg_name, origin_name)]
- if pool_name:
- args.extend(["--thinpool", pool_name])
- try:
- lvm(args)
- except LVMError as msg:
- raise LVMError("lvcreate (snapshot) failed for %s/%s: %s" % (vg_name, snap_name, msg))
-
-def thinlvpoolname(vg_name, lv_name):
- args = ["lvs", "--noheadings", "-o", "pool_lv"] + \
- ["%s/%s" % (vg_name, lv_name)]
-
- lines = lvm(args, capture=True, ignore_errors=True)
- try:
- pool = lines[0].strip()
- except IndexError:
- pool = ''
-
- return pool
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
index cb39b07..984ed82 100644
--- a/blivet/devices/lvm.py
+++ b/blivet/devices/lvm.py
@@ -25,6 +25,7 @@
import pprint
import re
from gi.repository import BlockDev as blockdev
+from gi.repository import GLib
# device backend modules
from ..devicelibs import lvm
@@ -195,13 +196,13 @@ def _teardown(self, recursive=None):
""" Close, or tear down, a device. """
log_method_call(self, self.name, status=self.status,
controllable=self.controllable)
- lvm.vgdeactivate(self.name)
+ blockdev.lvm_vgdeactivate(self.name)
def _create(self):
""" Create the device. """
log_method_call(self, self.name, status=self.status)
pv_list = [pv.path for pv in self.parents]
- lvm.vgcreate(self.name, pv_list, self.peSize)
+ blockdev.lvm_vgcreate(self.name, pv_list, self.peSize)
def _postCreate(self):
self._complete = True
@@ -224,9 +225,9 @@ def _destroy(self):
# the same name that we want to keep/use.
return
- lvm.vgreduce(self.name, None, missing=True)
- lvm.vgdeactivate(self.name)
- lvm.vgremove(self.name)
+ blockdev.lvm_vgreduce(self.name, None)
+ blockdev.lvm_vgdeactivate(self.name)
+ blockdev.lvm_vgremove(self.name)
def _remove(self, member):
status = []
@@ -235,15 +236,15 @@ def _remove(self, member):
if lv.exists:
lv.setup()
- lvm.pvmove(member.path)
- lvm.vgreduce(self.name, member.path)
+ blockdev.lvm_pvmove(member.path)
+ blockdev.lvm_vgreduce(self.name, member.path)
for (lv, status) in zip(self.lvs, status):
if lv.status and not status:
lv.teardown()
def _add(self, member):
- lvm.vgextend(self.name, member.path)
+ blockdev.lvm_vgextend(self.name, member.path)
def _addLogVol(self, lv):
""" Add an LV to this VG. """
@@ -365,11 +366,11 @@ def freeExtents(self):
# TODO: just ask lvm if isModified returns False
return int(self.freeSpace / self.peSize)
- def align(self, size, roundup=None):
+ def align(self, size, roundup=False):
""" Align a size to a multiple of physical extent size. """
size = util.numeric_type(size)
- return lvm.clampSize(size, self.peSize, roundup=roundup)
+ return Size(blockdev.lvm_round_size_to_pe(size, self.peSize, roundup))
@property
def pvs(self):
@@ -622,13 +623,13 @@ def _setup(self, orig=False):
""" Open, or set up, a device. """
log_method_call(self, self.name, orig=orig, status=self.status,
controllable=self.controllable)
- lvm.lvactivate(self.vg.name, self._name)
+ blockdev.lvm_lvactivate(self.vg.name, self._name)
def _teardown(self, recursive=None):
""" Close, or tear down, a device. """
log_method_call(self, self.name, status=self.status,
controllable=self.controllable)
- lvm.lvdeactivate(self.vg.name, self._name)
+ blockdev.lvm_lvdeactivate(self.vg.name, self._name)
def _postTeardown(self, recursive=False):
try:
@@ -646,14 +647,14 @@ def _preCreate(self):
super(LVMLogicalVolumeDevice, self)._preCreate()
try:
- vg_info = lvm.vginfo(self.vg.name)
- except errors.LVMError as lvmerr:
+ vg_info = blockdev.lvm_vginfo(self.vg.name)
+ except GLib.GError as lvmerr:
log.error("Failed to get free space for the %s VG: %s", self.vg.name, lvmerr)
# nothing more can be done, we don't know the VG's free space
return
- extent_size = Size(vg_info["LVM2_VG_EXTENT_SIZE"] + "MiB")
- extents_free = int(vg_info["LVM2_VG_FREE_COUNT"])
+ extent_size = Size(vg_info.extent_size)
+ extents_free = vg_info.free_count
can_use = extent_size * extents_free
if self.size > can_use:
@@ -666,7 +667,7 @@ def _create(self):
""" Create the device. """
log_method_call(self, self.name, status=self.status)
# should we use --zero for safety's sake?
- lvm.lvcreate(self.vg.name, self._name, self.size)
+ blockdev.lvm_lvcreate(self.vg.name, self._name, self.size)
def _preDestroy(self):
StorageDevice._preDestroy(self)
@@ -676,7 +677,7 @@ def _preDestroy(self):
def _destroy(self):
""" Destroy the device. """
log_method_call(self, self.name, status=self.status)
- lvm.lvremove(self.vg.name, self._name)
+ blockdev.lvm_lvremove(self.vg.name, self._name)
def resize(self):
log_method_call(self, self.name, status=self.status)
@@ -690,7 +691,7 @@ def resize(self):
self.format.teardown()
udev.settle()
- lvm.lvresize(self.vg.name, self._name, self.size)
+ blockdev.lvm_lvresize(self.vg.name, self._name, self.size)
@property
def isleaf(self):
@@ -879,7 +880,7 @@ def merge(self):
pass
udev.settle()
- lvm.lvsnapshotmerge(self.vg.name, self.lvname) # pylint: disable=no-member
+ blockdev.lvm_lvsnapshotmerge(self.vg.name, self.lvname) # pylint: disable=no-member
class LVMSnapShotDevice(LVMSnapShotBase, LVMLogicalVolumeDevice):
@@ -944,8 +945,7 @@ def teardown(self, recursive=False):
def _create(self):
""" Create the device. """
log_method_call(self, self.name, status=self.status)
- lvm.lvsnapshotcreate(self.vg.name, self._name, self.size,
- self.origin.lvname)
+ blockdev.lvm_lvsnapshotcreate(self.vg.name, self.origin.lvname, self._name, self.size)
def _destroy(self):
""" Destroy the device. """
@@ -953,7 +953,7 @@ def _destroy(self):
# old-style snapshots' status is tied to the origin's so we never
# explicitly activate or deactivate them and we have to tell lvremove
# that it is okay to remove the active snapshot
- lvm.lvremove(self.vg.name, self._name, force=True)
+ blockdev.lvm_lvremove(self.vg.name, self._name, force=True)
def _getPartedDevicePath(self):
return "%s-cow" % self.path
@@ -1007,11 +1007,11 @@ def __init__(self, name, parents=None, size=None, uuid=None,
"""
if metadatasize is not None and \
- not lvm.is_valid_thin_pool_metadata_size(metadatasize):
+ not blockdev.lvm_is_valid_thpool_md_size(metadatasize):
raise ValueError("invalid metadatasize value")
if chunksize is not None and \
- not lvm.is_valid_thin_pool_chunk_size(chunksize):
+ not blockdev.lvm_is_valid_thpool_chunk_size(chunksize):
raise ValueError("invalid chunksize value")
super(LVMThinPoolDevice, self).__init__(name, parents=parents,
@@ -1053,7 +1053,7 @@ def lvs(self):
@property
def vgSpaceUsed(self):
space = super(LVMThinPoolDevice, self).vgSpaceUsed
- space += lvm.get_pool_padding(space, pesize=self.vg.peSize)
+ space += Size(blockdev.lvm_get_thpool_padding(space, self.vg.peSize))
return space
@property
@@ -1070,12 +1070,12 @@ def _create(self):
if self.profile:
profile_name = self.profile.name
else:
- profile_name = ""
+ profile_name = None
# TODO: chunk size, data/metadata split --> profile
- lvm.thinpoolcreate(self.vg.name, self.lvname, self.size,
- metadatasize=self.metaDataSize,
- chunksize=self.chunkSize,
- profile=profile_name)
+ blockdev.lvm_thpoolcreate(self.vg.name, self.lvname, self.size,
+ md_size=self.metaDataSize,
+ chunk_size=self.chunkSize,
+ profile=profile_name)
def dracutSetupArgs(self):
return set()
@@ -1141,8 +1141,8 @@ def _preCreate(self):
def _create(self):
""" Create the device. """
log_method_call(self, self.name, status=self.status)
- lvm.thinlvcreate(self.vg.name, self.pool.lvname, self.lvname,
- self.size)
+ blockdev.lvm_thlvcreate(self.vg.name, self.pool.lvname, self.lvname,
+ self.size)
def removeHook(self, modparent=True):
if modparent:
@@ -1212,7 +1212,7 @@ def _setup(self, orig=False):
""" Open, or set up, a device. """
log_method_call(self, self.name, orig=orig, status=self.status,
controllable=self.controllable)
- lvm.lvactivate(self.vg.name, self._name, ignore_skip=True)
+ blockdev.lvm_lvactivate(self.vg.name, self._name, ignore_skip=True)
def _create(self):
""" Create the device. """
@@ -1223,8 +1223,8 @@ def _create(self):
# to use
pool_name = self.pool.lvname
- lvm.thinsnapshotcreate(self.vg.name, self._name, self.origin.lvname,
- pool_name=pool_name)
+ blockdev.lvm_thsnapshotcreate(self.vg.name, self._name, self.origin.lvname,
+ pool_name=pool_name)
def dependsOn(self, dep):
# once a thin snapshot exists it no longer depends on its origin
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index c7ffd91..df13c57 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -170,22 +170,24 @@ def addIgnoredDisk(self, disk):
@property
def pvInfo(self):
- if self._pvInfo is None:
- self._pvInfo = lvm.pvinfo() # pylint: disable=attribute-defined-outside-init
+ if self._pvs_cache is None:
+ pvs = blockdev.lvm_pvs()
+ self._pvs_cache = dict((pv.pv_name, pv) for pv in pvs) # pylint: disable=attribute-defined-outside-init
- return self._pvInfo
+ return self._pvs_cache
@property
def lvInfo(self):
- if self._lvInfo is None:
- self._lvInfo = lvm.lvs() # pylint: disable=attribute-defined-outside-init
+ if self._lvs_cache is None:
+ lvs = blockdev.lvm_lvs()
+ self._lvs_cache = dict((lv.lv_name, lv) for lv in lvs) # pylint: disable=attribute-defined-outside-init
- return self._lvInfo
+ return self._lvs_cache
def dropLVMCache(self):
""" Drop cached lvm information. """
- self._pvInfo = None # pylint: disable=attribute-defined-outside-init
- self._lvInfo = None # pylint: disable=attribute-defined-outside-init
+ self._pvs_cache = None # pylint: disable=attribute-defined-outside-init
+ self._lvs_cache = None # pylint: disable=attribute-defined-outside-init
def pruneActions(self):
""" Remove redundant/obsolete actions from the action list. """
@@ -1363,7 +1365,7 @@ def handleVgLvs(self, vg_device):
""" Handle setup of the LV's in the vg_device. """
vg_name = vg_device.name
lv_info = dict((k, v) for (k, v) in iter(self.lvInfo.items())
- if udev.device_get_vg_name(v) == vg_name)
+ if v.vg_name == vg_name)
self.names.extend(n for n in lv_info.keys() if n not in self.names)
@@ -1400,11 +1402,11 @@ def addRequiredLV(name, msg):
def addLV(lv):
""" Instantiate and add an LV based on data from the VG. """
- lv_name = udev.device_get_lv_name(lv)
- lv_uuid = udev.device_get_lv_uuid(lv)
- lv_attr = udev.device_get_lv_attr(lv)
- lv_size = udev.device_get_lv_size(lv)
- lv_type = udev.device_get_lv_type(lv)
+ lv_name = lv.lv_name
+ lv_uuid = lv.uuid
+ lv_attr = lv.attr
+ lv_size = Size(lv.size)
+ lv_type = lv.segtype
lv_class = LVMLogicalVolumeDevice
lv_parents = [vg_device]
@@ -1418,7 +1420,7 @@ def addLV(lv):
if lv_attr[0] in 'Ss':
log.info("found lvm snapshot volume '%s'", name)
- origin_name = lvm.lvorigin(vg_name, lv_name)
+ origin_name = blockdev.lvm_lvorigin(vg_name, lv_name)
if not origin_name:
log.error("lvm snapshot '%s-%s' has unknown origin",
vg_name, lv_name)
@@ -1468,11 +1470,11 @@ def addLV(lv):
lv_class = LVMThinPoolDevice
elif lv_attr[0] == 'V':
# thin volume
- pool_name = lvm.thinlvpoolname(vg_name, lv_name)
+ pool_name = blockdev.lvm_thlvpoolname(vg_name, lv_name)
pool_device_name = "%s-%s" % (vg_name, pool_name)
addRequiredLV(pool_device_name, "failed to look up thin pool")
- origin_name = lvm.lvorigin(vg_name, lv_name)
+ origin_name = blockdev.lvm_lvorigin(vg_name, lv_name)
if origin_name:
origin_device_name = "%s-%s" % (vg_name, origin_name)
addRequiredLV(origin_device_name, "failed to locate origin lv")
@@ -1539,13 +1541,12 @@ def addLV(lv):
def handleUdevLVMPVFormat(self, info, device):
# pylint: disable=unused-argument
log_method_call(self, name=device.name, type=device.format.type)
- pv_info = self.pvInfo.get(device.path, {})
- # lookup/create the VG and LVs
- try:
- vg_name = udev.device_get_vg_name(pv_info)
- vg_uuid = udev.device_get_vg_uuid(pv_info)
- except KeyError:
- # no vg name means no vg -- we're done with this pv
+ pv_info = self.pvInfo.get(device.path, None)
+ if pv_info:
+ vg_name = pv_info.vg_name
+ vg_uuid = pv_info.vg_uuid
+ else:
+ # no info about the PV -> we're done
return
if not vg_name:
@@ -1563,12 +1564,12 @@ def handleUdevLVMPVFormat(self, info, device):
raise UnusableConfigurationError("multiple LVM volume groups with the same name")
try:
- vg_size = udev.device_get_vg_size(pv_info)
- vg_free = udev.device_get_vg_free(pv_info)
- pe_size = udev.device_get_vg_extent_size(pv_info)
- pe_count = udev.device_get_vg_extent_count(pv_info)
- pe_free = udev.device_get_vg_free_extents(pv_info)
- pv_count = udev.device_get_vg_pv_count(pv_info)
+ vg_size = Size(pv_info.vg_size)
+ vg_free = Size(pv_info.vg_free)
+ pe_size = Size(pv_info.vg_extent_size)
+ pe_count = pv_info.vg_extent_count
+ pe_free = pv_info.vg_free_count
+ pv_count = pv_info.vg_pv_count
except (KeyError, ValueError) as e:
log.warning("invalid data for %s: %s", device.name, e)
return
@@ -1821,20 +1822,20 @@ def handleUdevDeviceFormat(self, info, device):
kwargs["biosraid"] = udev.device_is_biosraid_member(info)
elif format_type == "LVM2_member":
# lvm
- pv_info = self.pvInfo.get(device.path, {})
-
- try:
- kwargs["vgName"] = udev.device_get_vg_name(pv_info)
- except KeyError:
- log.warning("PV %s has no vg_name", name)
- try:
- kwargs["vgUuid"] = udev.device_get_vg_uuid(pv_info)
- except KeyError:
- log.warning("PV %s has no vg_uuid", name)
- try:
- kwargs["peStart"] = udev.device_get_pv_pe_start(pv_info)
- except KeyError:
- log.warning("PV %s has no pe_start", name)
+ pv_info = self.pvInfo.get(device.path, None)
+ if pv_info:
+ if pv_info.vg_name:
+ kwargs["vgName"] = pv_info.vg_name
+ else:
+ log.warning("PV %s has no vg_name", name)
+ if pv_info.vg_uuid:
+ kwargs["vgUuid"] = pv_info.vg_uuid
+ else:
+ log.warning("PV %s has no vg_uuid", name)
+ if pv_info.pe_start:
+ kwargs["peStart"] = Size(pv_info.pe_start)
+ else:
+ log.warning("PV %s has no pe_start", name)
elif format_type == "vfat":
# efi magic
if isinstance(device, PartitionDevice) and device.bootable:
diff --git a/blivet/errors.py b/blivet/errors.py
index c6d64a7..b05c0c7 100644
--- a/blivet/errors.py
+++ b/blivet/errors.py
@@ -111,9 +111,6 @@ class RaidError(StorageError):
class DMError(StorageError):
pass
-class LVMError(StorageError):
- pass
-
class MPathError(StorageError):
pass
diff --git a/blivet/formats/lvmpv.py b/blivet/formats/lvmpv.py
index efda438..069cccf 100644
--- a/blivet/formats/lvmpv.py
+++ b/blivet/formats/lvmpv.py
@@ -21,12 +21,15 @@
#
import os
+from gi.repository import BlockDev as blockdev
+from gi.repository import GLib
from ..storage_log import log_method_call
from parted import PARTITION_LVM
-from ..errors import LVMError, PhysicalVolumeError
+from ..errors import PhysicalVolumeError
from ..devicelibs import lvm
from ..i18n import N_
+from ..size import Size
from . import DeviceFormat, register_device_format
import logging
@@ -74,7 +77,7 @@ def __init__(self, **kwargs):
# liblvm may be able to tell us this at some point, even
# for not-yet-created devices
self.peStart = kwargs.get("peStart", lvm.LVM_PE_START)
- self.dataAlignment = kwargs.get("dataAlignment")
+ self.dataAlignment = kwargs.get("dataAlignment", Size(0))
self.inconsistentVG = False
@@ -117,12 +120,12 @@ def create(self, **kwargs):
# lvm has issues with persistence of metadata, so here comes the
# hammer...
DeviceFormat.destroy(self, **kwargs)
- lvm.pvscan(self.device)
- lvm.pvcreate(self.device, data_alignment=self.dataAlignment)
+ blockdev.lvm_pvscan(self.device)
+ blockdev.lvm_pvcreate(self.device, data_alignment=self.dataAlignment)
except Exception:
raise
finally:
- lvm.pvscan(self.device)
+ blockdev.lvm_pvscan(self.device)
self.exists = True
self.notifyKernel()
@@ -143,11 +146,11 @@ def destroy(self, **kwargs):
# FIXME: verify path exists?
try:
- lvm.pvremove(self.device)
- except LVMError:
+ blockdev.lvm_pvremove(self.device)
+ except GLib.GError:
DeviceFormat.destroy(self, **kwargs)
finally:
- lvm.pvscan(self.device)
+ blockdev.lvm_pvscan(self.device)
self.exists = False
self.notifyKernel()
diff --git a/blivet/partitioning.py b/blivet/partitioning.py
index 17da6e0..9c3f47d 100644
--- a/blivet/partitioning.py
+++ b/blivet/partitioning.py
@@ -22,13 +22,13 @@
from operator import gt, lt
from decimal import Decimal
+from gi.repository import BlockDev as blockdev
import parted
from .errors import DeviceError, PartitioningError
from .flags import flags
from .devices import PartitionDevice, LUKSDevice, devicePathToName
-from .devicelibs.lvm import get_pool_padding
from .size import Size
from .i18n import _
from .util import stringize, unicodeize
@@ -1789,8 +1789,7 @@ def _apply_chunk_growth(chunk):
# reduce the size of thin pools by the pad size
if hasattr(req.device, "lvs"):
- size -= get_pool_padding(size, pesize=req.device.vg.peSize,
- reverse=True)
+ size -= Size(blockdev.lvm_get_thpool_padding(size, req.device.vg.peSize, included=True))
# Base is pe, which means potentially rounded up by as much as
# pesize-1. As a result, you can't just add the growth to the
@@ -1830,7 +1829,7 @@ def growLVM(storage):
lv.req_size = max(lv.req_size, lv.usedSpace)
# add the required padding to the requested pool size
- lv.req_size += get_pool_padding(lv.req_size, pesize=vg.peSize)
+ lv.req_size += Size(blockdev.lvm_get_thpool_padding(lv.req_size, vg.peSize))
# establish sizes for the percentage-based requests (which are fixed)
percentage_based_lvs = [lv for lv in vg.lvs if lv.req_percent]
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/8c996463e0b395db85e3fd612964ad376f38ff09
More information about the anaconda-patches
mailing list