From 21a740f5a338c7235731a8b9e2be62db300dfd5c Mon Sep 17 00:00:00 2001
From: David Lehman <dlehman@redhat.com>
Date: Thu, 28 Feb 2013 08:52:28 -0600
Subject: [PATCH 1/5] Add DeviceFactory support for lvm-on-md.

---
 blivet/devicefactory.py | 57 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 48 insertions(+), 9 deletions(-)

diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py
index f548cc5..d16068f 100644
--- a/blivet/devicefactory.py
+++ b/blivet/devicefactory.py
@@ -586,6 +586,8 @@ class DeviceFactory(object):
                     raise ErrorRecoveryFailure("failed to revert device size")
 
                 raise(e)
+
+            ret = device
         elif self.new_device_attr:
             log.debug("creating new device")
             if self.encrypted and self.encrypt_leaves:
@@ -648,6 +650,7 @@ class DeviceFactory(object):
                 _container_post_error()
                 raise StorageError(e)
 
+            ret = device
             if self.encrypted and self.encrypt_leaves:
                 fmt = getFormat(luks_fmt_type,
                                 mountpoint=luks_mountpoint,
@@ -655,7 +658,9 @@ class DeviceFactory(object):
                 luks_device = LUKSDevice("luks-" + device.name,
                                          parents=[device], format=fmt)
                 self.storage.createDevice(luks_device)
+                ret = luks_device
 
+        return ret
 
 class DiskFactory(DeviceFactory):
     type_desc = "disk"
@@ -765,8 +770,8 @@ class LVMFactory(DeviceFactory):
     new_container_attr = "newVG"
     new_device_attr = "newLV"
     container_list_attr = "vgs"
-    encrypt_members = True
-    encrypt_leaves = False
+    encrypt_members = True      # this should be settable per-instance
+    encrypt_leaves = False      # this should be settable per-instance
 
     def handle_no_size(self, device=None, container=None):
         """ Set device size so that it grows to the largest size possible. """
@@ -783,20 +788,27 @@ class LVMFactory(DeviceFactory):
                                                    container=container)
 
     @property
+    def size_func_kwargs(self):
+        kwargs = {}
+        if not getattr(self, "lvm_on_md"):
+            if self.raid_level in ("raid1", "raid10"):
+                kwargs["mirrored"] = True
+            if self.raid_level in ("raid0", "raid10"):
+                kwargs["striped"] = True
+
+        return kwargs
+
+    @property
     def device_size(self):
-        size_func_kwargs = {}
-        if self.raid_level in ("raid1", "raid10"):
-            size_func_kwargs["mirrored"] = True
-        if self.raid_level in ("raid0", "raid10"):
-            size_func_kwargs["striped"] = True
-        return get_pv_space(self.size, len(self.disks), **size_func_kwargs)
+        return get_pv_space(self.size, len(self.disks), **self.size_func_kwargs)
 
     def container_size_func(self, container, device=None):
         size = sum([p.size for p in container.parents])
         size -= container.freeSpace
         size += self.device_size
         if device:
-            size -= get_pv_space(device.size, len(container.parents))
+            size -= get_pv_space(device.size, len(container.parents),
+                                 **self.size_func_kwargs)
 
         return size
 
@@ -825,6 +837,33 @@ class LVMFactory(DeviceFactory):
 
         return size
 
+class LVMOnMDFactory(LVMFactory):
+    lvm_on_md = True
+
+    def set_container_members(self, container, members=None, device=None):
+        """ Set up and return the container's member devices. """
+        log_members = []
+        if members:
+            log_members = [str(m) for m in members]
+        log_method_call(self, container=container,
+                        members=log_members, device=device)
+
+        pv_name = self.storage.suggestDeviceName(prefix="pv")
+        pv_device = None
+        md_size = self.device_size
+        if container:
+            # get a proper container size estimate and pass any existing
+            # member device into configure_device
+            md_size = self.container_size_func(container, device)
+            pv_device = container.parents[0]    # XXX single pv, right?
+
+        md_factory = MDFactory(self.storage, md_size, self.disks,
+                               self.raid_level, self.encrypted)
+        member = md_factory.configure_device(name=pv_name,
+                                             device=pv_device,
+                                             fstype=self.member_format)
+        return [member]
+
 class MDFactory(DeviceFactory):
     type_desc = "md"
     member_format = "mdmember"
-- 
1.8.1.4

