[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH 04/16] Add support for linear device-mapper devices.



DMLinearDevice is treated like a disk, meaning it can be partitioned.
Like the other device-mapper disk types, it will not have a meaningful
teardown method.

Move setupPartitions up into DMDevice so it can be used by both
DMLinearDevice and MultipathDevice. Also add teardownPartitions even
though it won't get called as of now. Move "slave" property up into
DMDevice also, since all DMDevice subclasses require at least one
backing device.
---
 pyanaconda/storage/devicelibs/dm.py |   24 +++++++
 pyanaconda/storage/devices.py       |  124 ++++++++++++++++++++++++++++++-----
 2 files changed, 132 insertions(+), 16 deletions(-)

diff --git a/pyanaconda/storage/devicelibs/dm.py b/pyanaconda/storage/devicelibs/dm.py
index e526377..9e2f68c 100644
--- a/pyanaconda/storage/devicelibs/dm.py
+++ b/pyanaconda/storage/devicelibs/dm.py
@@ -32,6 +32,30 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
 import logging
 log = logging.getLogger("storage")
 
+def dm_setup(args, progress=None):
+    ret = iutil.execWithPulseProgress("dmsetup", args,
+                                     stdout = "/dev/tty5",
+                                     stderr = "/dev/tty5",
+                                     progress=progress)
+    if ret.rc:
+        raise DMError(ret.stderr)
+
+def dm_create_linear(map_name, device, length, uuid):
+    table = "0 %d linear %s 0" % (length, device)
+    args = ["create", map_name, "--uuid", uuid, "--table", "%s" % table]
+    try:
+        dm_setup(args)
+    except DMError as msg:
+        raise DMError("dm_create_linear (%s, %d, %s) failed: %s"
+                                % (map_name, length, device, msg))
+
+def dm_remove(map_name):
+    args = ["remove", map_name]
+    try:
+        dm_setup(args)
+    except DMError as msg:
+        raise DMError("dm_remove (%s) failed: %s" % (map_name, msg))
+
 def name_from_dm_node(dm_node):
     name = block.getNameFromDmNode(dm_node)
     if name is not None:
diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py
index abc1d81..026d337 100644
--- a/pyanaconda/storage/devices.py
+++ b/pyanaconda/storage/devices.py
@@ -1593,6 +1593,26 @@ class DMDevice(StorageDevice):
 
         return dm.dm_node_from_name(self.name)
 
+    def setupPartitions(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        rc = iutil.execWithRedirect("kpartx",
+                                ["-a", "-p", "p", "/dev/mapper/%s" % self.name],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+        if rc:
+            raise DMError("partition activation failed for '%s'" % self.name)
+        udev_settle()
+
+    def teardownPartitions(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        rc = iutil.execWithRedirect("kpartx",
+                                ["-d", "-p", "p", "/dev/mapper/%s" % self.name],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+        if rc:
+            raise DMError("partition deactivation failed for '%s'" % self.name)
+        udev_settle()
+
     def _setName(self, name):
         """ Set the device's map name. """
         log_method_call(self, self.name, status=self.status)
@@ -1605,6 +1625,94 @@ class DMDevice(StorageDevice):
     name = property(lambda d: d._name,
                     lambda d,n: d._setName(n))
 
+    @property
+    def slave(self):
+        """ This device's backing device. """
+        return self.parents[0]
+
+
+class DMLinearDevice(DMDevice):
+    _type = "dm-linear"
+    _partitionable = True
+    _isDisk = True
+
+    def __init__(self, name, format=None, size=None, dmUuid=None,
+                 exists=None, parents=None, sysfsPath=''):
+        """ Create a DMLinearDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                size -- the device's size (units/format TBD)
+                dmUuid -- the device's device-mapper UUID
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                parents -- a list of required Device instances
+                exists -- indicates whether this is an existing device
+        """
+        if not parents:
+            raise ValueError("DMLinearDevice requires a backing block device")
+
+        dmUuid = "ANACONDA-%s" % name
+
+        DMDevice.__init__(self, name, format=format, size=size,
+                          parents=parents, sysfsPath=sysfsPath,
+                          exists=exists, target="linear", dmUuid=dmUuid)
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            return
+
+        self.slave.setup(orig=orig)
+        udev_settle()
+
+        slave_length = self.slave.partedDevice.length
+        dm.dm_create_linear(self.name, self.slave.path, slave_length,
+                            self.dmUuid)
+        udev_settle()
+        self.setupPartitions()
+        udev_settle()
+
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
+    def deactivate(self):
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            if self.originalFormat.exists:
+                self.originalFormat.teardown()
+            if self.format.exists:
+                self.format.teardown()
+            udev_settle()
+
+        self.teardownPartitions()
+        udev_settle()
+        dm.dm_remove(self.name)
+        udev_settle()
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        log.debug("not tearing down dm-linear device %s" % self.name)
+
+    @property
+    def description(self):
+        return self.model
+
 
 class DMCryptDevice(DMDevice):
     """ A dm-crypt device """
@@ -1738,11 +1846,6 @@ class LUKSDevice(DMCryptDevice):
     def req_grow(self):
         return getattr(self.slave, "req_grow", None)
 
-    @property
-    def slave(self):
-        """ This device's backing device. """
-        return self.parents[0]
-
     def dracutSetupString(self):
         return "rd_LUKS_UUID=luks-%s" % self.slave.format.uuid
 
@@ -3213,17 +3316,6 @@ class MultipathDevice(DMDevice):
         else:
             self.parents.append(parent)
 
-    def setupPartitions(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        rc = iutil.execWithRedirect("kpartx",
-                                ["-a", "-p", "p", "/dev/mapper/%s" % self.name],
-                                stdout = "/dev/tty5",
-                                stderr = "/dev/tty5")
-        if rc:
-            raise MPathError("multipath partition activation failed for '%s'" %
-                            self.name)
-        udev_settle()
-
     def teardown(self, recursive=None):
         """ Tear down the mpath device. """
         log_method_call(self, self.name, status=self.status)
-- 
1.7.3.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]