[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