From 1a701071a85e797a2f154c7c43ccfa203e92cf80 Mon Sep 17 00:00:00 2001
From: David Lehman <dlehman@redhat.com>
Date: Mon, 14 Jan 2013 17:48:37 -0600
Subject: [PATCH 09/11] Remove the storage module and replace it with blivet.

---
 anaconda                                          |   12 +-
 anaconda.spec.in                                  |   66 +-
 configure.ac                                      |   28 -
 po/POTFILES.in                                    |   26 -
 pyanaconda/Makefile.am                            |    2 +-
 pyanaconda/__init__.py                            |    4 +-
 pyanaconda/bootloader.py                          |   12 +-
 pyanaconda/exception.py                           |    4 +-
 pyanaconda/image.py                               |   22 +-
 pyanaconda/install.py                             |    2 +-
 pyanaconda/installclass.py                        |    6 +-
 pyanaconda/isys/__init__.py                       |    6 +-
 pyanaconda/kickstart.py                           |   44 +-
 pyanaconda/network.py                             |    8 +-
 pyanaconda/packaging/__init__.py                  |   22 +-
 pyanaconda/packaging/livepayload.py               |    8 +-
 pyanaconda/packaging/yumpayload.py                |   14 +-
 pyanaconda/rescue.py                              |   12 +-
 pyanaconda/storage/Makefile.am                    |   26 -
 pyanaconda/storage/__init__.py                    | 3533 -----------------
 pyanaconda/storage/arch.py                        |  315 --
 pyanaconda/storage/dasd.py                        |  218 --
 pyanaconda/storage/deviceaction.py                |  587 ---
 pyanaconda/storage/devicelibs/Makefile.am         |   24 -
 pyanaconda/storage/devicelibs/btrfs.py            |  112 -
 pyanaconda/storage/devicelibs/crypto.py           |  153 -
 pyanaconda/storage/devicelibs/dm.py               |   78 -
 pyanaconda/storage/devicelibs/edd.py              |  231 --
 pyanaconda/storage/devicelibs/loop.py             |   89 -
 pyanaconda/storage/devicelibs/lvm.py              |  403 --
 pyanaconda/storage/devicelibs/mdraid.py           |  280 --
 pyanaconda/storage/devicelibs/mpath.py            |  285 --
 pyanaconda/storage/devicelibs/swap.py             |  157 -
 pyanaconda/storage/devices.py                     | 4190 ---------------------
 pyanaconda/storage/devicetree.py                  | 2205 -----------
 pyanaconda/storage/errors.py                      |  193 -
 pyanaconda/storage/fcoe.py                        |  163 -
 pyanaconda/storage/flags.py                       |   98 -
 pyanaconda/storage/formats/Makefile.am            |   24 -
 pyanaconda/storage/formats/__init__.py            |  438 ---
 pyanaconda/storage/formats/biosboot.py            |   60 -
 pyanaconda/storage/formats/disklabel.py           |  443 ---
 pyanaconda/storage/formats/dmraid.py              |  114 -
 pyanaconda/storage/formats/fs.py                  | 1433 -------
 pyanaconda/storage/formats/luks.py                |  342 --
 pyanaconda/storage/formats/lvmpv.py               |  146 -
 pyanaconda/storage/formats/mdraid.py              |  120 -
 pyanaconda/storage/formats/multipath.py           |   94 -
 pyanaconda/storage/formats/prepboot.py            |   87 -
 pyanaconda/storage/formats/swap.py                |  171 -
 pyanaconda/storage/iscsi.py                       |  437 ---
 pyanaconda/storage/partitioning.py                | 1947 ----------
 pyanaconda/storage/partspec.py                    |   82 -
 pyanaconda/storage/platform.py                    |  409 --
 pyanaconda/storage/pyudev.py                      |  232 --
 pyanaconda/storage/size.py                        |  235 --
 pyanaconda/storage/storage_log.py                 |   46 -
 pyanaconda/storage/tsort.py                       |  105 -
 pyanaconda/storage/udev.py                        |  737 ----
 pyanaconda/storage/util.py                        |  272 --
 pyanaconda/storage/zfcp.py                        |  428 ---
 pyanaconda/timezone.py                            |    2 +-
 pyanaconda/ui/gui/spokes/custom.py                |   46 +-
 pyanaconda/ui/gui/spokes/lib/cart.py              |    2 +-
 pyanaconda/ui/gui/spokes/lib/resize.py            |    2 +-
 pyanaconda/ui/gui/spokes/storage.py               |    6 +-
 pyanaconda/ui/gui/tools/run-spoke.py              |    4 +-
 pyanaconda/ui/lib/space.py                        |    2 +-
 pyanaconda/ui/tui/spokes/storage.py               |    4 +-
 pyanaconda/ui/tui/tools/run-text-spoke.py         |    4 +-
 scripts/anaconda-cleanup                          |    6 +-
 tests/Makefile.am                                 |    2 +-
 tests/storage_test/Makefile.am                    |   24 -
 tests/storage_test/action_test.py                 |  926 -----
 tests/storage_test/devicelibs_test/Makefile.am    |   22 -
 tests/storage_test/devicelibs_test/baseclass.py   |   80 -
 tests/storage_test/devicelibs_test/crypto_test.py |  135 -
 tests/storage_test/devicelibs_test/edd_test.py    |  212 --
 tests/storage_test/devicelibs_test/lvm_test.py    |  239 --
 tests/storage_test/devicelibs_test/mdraid_test.py |  114 -
 tests/storage_test/devicelibs_test/mpath_test.py  |   86 -
 tests/storage_test/devicelibs_test/swap_test.py   |   74 -
 tests/storage_test/partitioning_test.py           |  130 -
 tests/storage_test/size_test.py                   |   86 -
 tests/storage_test/storagetestcase.py             |  287 --
 tests/storage_test/tsort_test.py                  |   62 -
 tests/storage_test/udev_test.py                   |  139 -
 87 files changed, 131 insertions(+), 24605 deletions(-)
 delete mode 100644 pyanaconda/storage/Makefile.am
 delete mode 100644 pyanaconda/storage/__init__.py
 delete mode 100644 pyanaconda/storage/arch.py
 delete mode 100644 pyanaconda/storage/dasd.py
 delete mode 100644 pyanaconda/storage/deviceaction.py
 delete mode 100644 pyanaconda/storage/devicelibs/Makefile.am
 delete mode 100644 pyanaconda/storage/devicelibs/__init__.py
 delete mode 100644 pyanaconda/storage/devicelibs/btrfs.py
 delete mode 100644 pyanaconda/storage/devicelibs/crypto.py
 delete mode 100644 pyanaconda/storage/devicelibs/dm.py
 delete mode 100644 pyanaconda/storage/devicelibs/edd.py
 delete mode 100644 pyanaconda/storage/devicelibs/loop.py
 delete mode 100644 pyanaconda/storage/devicelibs/lvm.py
 delete mode 100644 pyanaconda/storage/devicelibs/mdraid.py
 delete mode 100644 pyanaconda/storage/devicelibs/mpath.py
 delete mode 100644 pyanaconda/storage/devicelibs/swap.py
 delete mode 100644 pyanaconda/storage/devices.py
 delete mode 100644 pyanaconda/storage/devicetree.py
 delete mode 100644 pyanaconda/storage/errors.py
 delete mode 100644 pyanaconda/storage/fcoe.py
 delete mode 100644 pyanaconda/storage/flags.py
 delete mode 100644 pyanaconda/storage/formats/Makefile.am
 delete mode 100644 pyanaconda/storage/formats/__init__.py
 delete mode 100644 pyanaconda/storage/formats/biosboot.py
 delete mode 100644 pyanaconda/storage/formats/disklabel.py
 delete mode 100644 pyanaconda/storage/formats/dmraid.py
 delete mode 100644 pyanaconda/storage/formats/fs.py
 delete mode 100644 pyanaconda/storage/formats/luks.py
 delete mode 100644 pyanaconda/storage/formats/lvmpv.py
 delete mode 100644 pyanaconda/storage/formats/mdraid.py
 delete mode 100644 pyanaconda/storage/formats/multipath.py
 delete mode 100644 pyanaconda/storage/formats/prepboot.py
 delete mode 100644 pyanaconda/storage/formats/swap.py
 delete mode 100644 pyanaconda/storage/iscsi.py
 delete mode 100644 pyanaconda/storage/partitioning.py
 delete mode 100644 pyanaconda/storage/partspec.py
 delete mode 100644 pyanaconda/storage/platform.py
 delete mode 100644 pyanaconda/storage/pyudev.py
 delete mode 100644 pyanaconda/storage/size.py
 delete mode 100644 pyanaconda/storage/storage_log.py
 delete mode 100644 pyanaconda/storage/tsort.py
 delete mode 100644 pyanaconda/storage/udev.py
 delete mode 100644 pyanaconda/storage/util.py
 delete mode 100644 pyanaconda/storage/zfcp.py
 delete mode 100644 tests/storage_test/Makefile.am
 delete mode 100644 tests/storage_test/action_test.py
 delete mode 100644 tests/storage_test/devicelibs_test/Makefile.am
 delete mode 100644 tests/storage_test/devicelibs_test/baseclass.py
 delete mode 100755 tests/storage_test/devicelibs_test/crypto_test.py
 delete mode 100644 tests/storage_test/devicelibs_test/edd_test.py
 delete mode 100755 tests/storage_test/devicelibs_test/lvm_test.py
 delete mode 100755 tests/storage_test/devicelibs_test/mdraid_test.py
 delete mode 100755 tests/storage_test/devicelibs_test/mpath_test.py
 delete mode 100755 tests/storage_test/devicelibs_test/swap_test.py
 delete mode 100644 tests/storage_test/partitioning_test.py
 delete mode 100644 tests/storage_test/size_test.py
 delete mode 100644 tests/storage_test/storagetestcase.py
 delete mode 100644 tests/storage_test/tsort_test.py
 delete mode 100644 tests/storage_test/udev_test.py

diff --git a/anaconda b/anaconda
index 9ad9844..5cbb39d 100755
--- a/anaconda
+++ b/anaconda
@@ -409,8 +409,8 @@ def setupDisplay(anaconda, opts, addon_paths=None):
     from pyanaconda.ui.tui.spokes.askvnc import AskVNCSpoke
     from pykickstart.constants import DISPLAY_MODE_TEXT
     from pyanaconda import network
-    from pyanaconda.storage import arch
-    from pyanaconda.storage import util
+    from blivet import arch
+    import blivet.util
 
     graphical_failed = 0
     vncS = vnc.VncServer()          # The vnc Server object.
@@ -458,7 +458,7 @@ def setupDisplay(anaconda, opts, addon_paths=None):
             vncS.vncconnectport = anaconda.ksdata.vnc.port
 
     # disable VNC over text question when not enough memory is available
-    if util.total_memory() < isys.MIN_GUI_RAM:
+    if blivet.util.total_memory() < isys.MIN_GUI_RAM:
         flags.vncquestion = False
 
     # disable VNC question if text mode is requested and this is a ks install
@@ -930,8 +930,8 @@ if __name__ == "__main__":
     from pyanaconda.threads import initThreading, threadMgr, AnacondaThread
     initThreading()
 
-    from pyanaconda import storage
-    storage.enable_installer_mode()
+    import blivet
+    blivet.enable_installer_mode()
 
     # now start the interface
     setupDisplay(anaconda, opts, addon_paths)
@@ -977,7 +977,7 @@ if __name__ == "__main__":
         # this is lame, but make things match what we expect (#443408)
         opts.lang = opts.lang.replace(".utf8", ".UTF-8")
 
-    from pyanaconda.storage import storageInitialize
+    from blivet import storageInitialize
     from pyanaconda.packaging import payloadInitialize
     from pyanaconda.network import networkInitialize, wait_for_connecting_NM_thread
 
diff --git a/anaconda.spec.in b/anaconda.spec.in
index b3c81e7..1114144 100644
--- a/anaconda.spec.in
+++ b/anaconda.spec.in
@@ -19,41 +19,26 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 # Versions of required components (done so we make sure the buildrequires
 # match the requires versions of things).
-%define dmver 1.02.17-6
 %define gettextver 0.11
-%define genisoimagever 1.1.9-4
 %define gconfversion 2.28.1
 %define intltoolver 0.31.2-3
 %define libnlver 1.0
-%define libselinuxver 1.6
 %define pykickstartver 1.99.22
-%define rpmpythonver 4.2-0.61
 %define yumver 3.4.3-32
 %define partedver 1.8.1
 %define pypartedver 2.5-2
 %define pythonpyblockver 0.45
-%define e2fsver 1.41.0
 %define nmver 1:0.7.1-3.git20090414
 %define dbusver 1.2.3
-%define createrepover 0.4.7
 %define yumutilsver 1.1.11-3
-%define iscsiver 6.2.0.870-3
-%define pythoncryptsetupver 0.1.1
 %define mehver 0.21-1
 %define sckeyboardver 1.3.1
-%define libblkidver 2.17.1-1
-%define fcoeutilsver 1.0.12-3.20100323git
 %define firewalldver 0.2.9-1
 %define pythonurlgrabberver 3.9.1-5
 %define utillinuxver 2.15.1
-%define syslinuxver 3.73
 %define dracutver 024-16
 
 BuildRequires: audit-libs-devel
-BuildRequires: bzip2-devel
-BuildRequires: device-mapper-devel >= %{dmver}
-BuildRequires: e2fsprogs-devel >= %{e2fsver}
-BuildRequires: elfutils-devel
 BuildRequires: gettext >= %{gettextver}
 BuildRequires: gtk3-devel
 BuildRequires: gtk-doc
@@ -61,30 +46,19 @@ BuildRequires: gobject-introspection-devel
 BuildRequires: glade-devel
 BuildRequires: pygobject3
 BuildRequires: intltool >= %{intltoolver}
-BuildRequires: libarchive-devel
 BuildRequires: libX11-devel
 BuildRequires: libXt-devel
 BuildRequires: libXxf86misc-devel
-BuildRequires: libblkid-devel >= %{libblkidver}
-BuildRequires: libcurl-devel
 BuildRequires: libgnomekbd-devel
 BuildRequires: libnl-devel >= %{libnlver}
-BuildRequires: libselinux-devel >= %{libselinuxver}
-BuildRequires: libsepol-devel
 BuildRequires: libxklavier-devel
-BuildRequires: libxml2-python
 BuildRequires: pango-devel
 BuildRequires: pykickstart >= %{pykickstartver}
 BuildRequires: python-devel
-BuildRequires: python-pyblock >= %{pythonpyblockver}
 BuildRequires: python-urlgrabber >= %{pythonurlgrabberver}
 BuildRequires: python-nose
-BuildRequires: rpm-devel
-BuildRequires: rpm-python >= %{rpmpythonver}
 BuildRequires: systemd
-BuildRequires: xmlto
 BuildRequires: yum >= %{yumver}
-BuildRequires: zlib-devel
 BuildRequires: NetworkManager-devel >= %{nmver}
 BuildRequires: NetworkManager-glib-devel >= %{nmver}
 BuildRequires: dbus-devel >= %{dbusver}
@@ -92,41 +66,26 @@ BuildRequires: dbus-python
 %ifarch %livearches
 BuildRequires: desktop-file-utils
 %endif
-BuildRequires: iscsi-initiator-utils-devel >= %{iscsiver}
 %ifarch s390 s390x
 BuildRequires: s390utils-devel
 %endif
 
 Requires: anaconda-widgets = %{version}-%{release}
+Requires: python-blivet
 Requires: gnome-icon-theme-symbolic
 Requires: python-meh >= %{mehver}
-Requires: policycoreutils
+Requires: libselinux-python
 Requires: rpm-python >= %{rpmpythonver}
 Requires: parted >= %{partedver}
 Requires: pyparted >= %{pypartedver}
 Requires: yum >= %{yumver}
-Requires: libxml2-python
 Requires: python-urlgrabber >= %{pythonurlgrabberver}
 Requires: system-logos
 Requires: pykickstart >= %{pykickstartver}
-Requires: device-mapper >= %{dmver}
-Requires: device-mapper-libs >= %{dmver}
-Requires: dosfstools
-Requires: e2fsprogs >= %{e2fsver}
-Requires: gzip
-Requires: libarchive
 Requires: python-babel
-%ifarch %{ix86} x86_64 ia64
-Requires: dmidecode
-%endif
-Requires: python-pyblock >= %{pythonpyblockver}
 Requires: libuser-python
 Requires: authconfig
 Requires: firewalld >= %{firewalldver}
-Requires: cryptsetup-luks
-Requires: python-cryptsetup >= %{pythoncryptsetupver}
-Requires: mdadm
-Requires: lvm2
 Requires: util-linux >= %{utillinuxver}
 Requires: dbus-python
 Requires: python-pwquality
@@ -140,18 +99,7 @@ Requires: libgnomekbd
 Requires: usermode
 Requires: zenity
 %endif
-Requires: createrepo >= %{createrepover}
-Requires: squashfs-tools
-%if ! 0%{?rhel}
-Requires: hfsplus-tools
-%endif
-Requires: genisoimage >= %{genisoimagever}
 Requires: GConf2 >= %{gconfversion}
-%ifarch %{ix86} x86_64
-Requires: syslinux >= %{syslinuxver}
-Requires: makebootfat
-Requires: device-mapper
-%endif
 %ifarch s390 s390x
 Requires: openssh
 %endif
@@ -162,21 +110,11 @@ Requires: nm-connection-editor
 Requires: dhclient
 Requires: anaconda-yum-plugins
 Requires: libselinux-python >= %{libselinuxver}
-%ifnarch s390 s390x
-Requires: fcoe-utils >= %{fcoeutilsver}
-%endif
-Requires: device-mapper-multipath
 Requires: kbd
 Requires: chrony
 Requires: rdate
 Requires: rsync
 Requires: hostname
-%ifarch %{sparc}
-Requires: elftoaout piggyback
-%endif
-%ifarch x86_64
-Requires: mactel-boot
-%endif
 Obsoletes: anaconda-images <= 10
 Provides: anaconda-images = %{version}-%{release}
 Obsoletes: anaconda-runtime < %{version}-%{release}
diff --git a/configure.ac b/configure.ac
index f43a012..da50f5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -111,10 +111,7 @@ PKG_CHECK_MODULES([GDK], [gdk-3.0])
 PKG_CHECK_MODULES([NETWORKMANAGER], [NetworkManager >= 0.7.1])
 PKG_CHECK_MODULES([LIBNL], [libnl-1 >= 1.0])
 PKG_CHECK_MODULES([LIBNM_GLIB], [libnm-glib >= 0.7.1 libnm-util >= 0.7.1])
-PKG_CHECK_MODULES([DEVMAPPER], [devmapper >= 1.02.17])
 PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.19.5])
-PKG_CHECK_MODULES([RPM], [rpm >= 4.8.0])
-PKG_CHECK_MODULES([LIBARCHIVE], [libarchive >= 2.7.902a])
 
 # Set $RPM_OPT_FLAGS if we don't have it
 if test -z $RPM_OPT_FLAGS ; then
@@ -123,32 +120,12 @@ else
     CFLAGS="$CFLAGS $RPM_OPT_FLAGS"
 fi
 
-# SELinux support can be enabled or disabled
-AC_ARG_ENABLE(selinux,
-    AC_HELP_STRING([--enable-selinux],
-                   [enable SELinux support (default is yes)]),
-    [selinux=$enableval],
-    [selinux=yes])
-if test x$selinux = xyes ; then
-    AC_CHECK_LIB([selinux], [matchpathcon], [],
-        [AC_MSG_FAILURE([*** libselinux not usable.])])
-    AC_CHECK_LIB([selinux], [lsetfilecon], [],
-        [AC_MSG_FAILURE([*** libselinux not usable.])])
-
-    selinux_libs="-lselinux -laudit"
-    AC_SUBST(SELINUX_CFLAGS, [-DUSESELINUX=1])
-    AC_SUBST(SELINUX_LIBS, [$selinux_libs])
-fi
-
 # NFS support can, in theory, be enabled or disabled
 AC_ARG_ENABLE(nfs,
     AC_HELP_STRING([--enable-nfs],
                    [enable NFS support (default is yes)]),
     [nfs=$enableval],
     [nfs=yes])
-if test x$selinux = xyes ; then
-    AC_SUBST(NFS_CFLAGS, [-DHAVE_NFS])
-fi
 
 # IPv6 support can be enabled or disabled
 AC_ARG_ENABLE(ipv6,
@@ -255,9 +232,6 @@ AC_CONFIG_FILES([Makefile
                  pyanaconda/Makefile
                  pyanaconda/isys/Makefile
                  pyanaconda/packaging/Makefile
-                 pyanaconda/storage/Makefile
-                 pyanaconda/storage/devicelibs/Makefile
-                 pyanaconda/storage/formats/Makefile
                  pyanaconda/ui/Makefile
                  pyanaconda/ui/lib/Makefile
                  pyanaconda/ui/gui/categories/Makefile
@@ -274,8 +248,6 @@ AC_CONFIG_FILES([Makefile
                  tests/Makefile
                  tests/mock/Makefile
                  tests/kickstart_test/Makefile
-                 tests/storage_test/Makefile
-                 tests/storage_test/devicelibs_test/Makefile
                  tests/pylint/Makefile
                  tests/regex/Makefile
                  tests/pyanaconda_test/Makefile
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1d7e264..172d48a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,7 +12,6 @@ pyanaconda/installinterfacebase.py
 pyanaconda/iutil.py
 pyanaconda/kickstart.py
 pyanaconda/network.py
-pyanaconda/platform.py
 pyanaconda/product.py
 pyanaconda/rescue.py
 pyanaconda/vnc.py
@@ -27,31 +26,6 @@ pyanaconda/packaging/livepayload.py
 pyanaconda/packaging/tarpayload.py
 pyanaconda/packaging/yumpayload.py
 
-# Storage module source files
-pyanaconda/storage/__init__.py
-pyanaconda/storage/dasd.py
-pyanaconda/storage/deviceaction.py
-pyanaconda/storage/devicelibs/crypto.py
-pyanaconda/storage/devicelibs/dm.py
-pyanaconda/storage/devicelibs/lvm.py
-pyanaconda/storage/devicelibs/mdraid.py
-pyanaconda/storage/devicelibs/swap.py
-pyanaconda/storage/devices.py
-pyanaconda/storage/devicetree.py
-pyanaconda/storage/fcoe.py
-pyanaconda/storage/formats/__init__.py
-pyanaconda/storage/formats/disklabel.py
-pyanaconda/storage/formats/dmraid.py
-pyanaconda/storage/formats/fs.py
-pyanaconda/storage/formats/luks.py
-pyanaconda/storage/formats/lvmpv.py
-pyanaconda/storage/formats/mdraid.py
-pyanaconda/storage/formats/multipath.py
-pyanaconda/storage/formats/swap.py
-pyanaconda/storage/iscsi.py
-pyanaconda/storage/partitioning.py
-pyanaconda/storage/zfcp.py
-
 # Interfaces
 pyanaconda/ui/common.py
 pyanaconda/ui/__init__.py
diff --git a/pyanaconda/Makefile.am b/pyanaconda/Makefile.am
index d106f78..09b2b86 100644
--- a/pyanaconda/Makefile.am
+++ b/pyanaconda/Makefile.am
@@ -17,7 +17,7 @@
 #
 # Author: Martin Sivak <msivak@redhat.com>
 
-SUBDIRS = installclasses isys storage ui packaging
+SUBDIRS = installclasses isys ui packaging
 
 MAINTAINERCLEANFILES = Makefile.in
 
diff --git a/pyanaconda/__init__.py b/pyanaconda/__init__.py
index 4767080..aa38394 100644
--- a/pyanaconda/__init__.py
+++ b/pyanaconda/__init__.py
@@ -155,8 +155,8 @@ class Anaconda(object):
     @property
     def storage(self):
         if not self._storage:
-            import storage
-            self._storage = storage.Storage(data=self.ksdata)
+            import blivet
+            self._storage = blivet.Blivet(ksdata=self.ksdata)
 
         return self._storage
 
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
index 4d7d38f..7e77071 100644
--- a/pyanaconda/bootloader.py
+++ b/pyanaconda/bootloader.py
@@ -28,15 +28,15 @@ import struct
 from parted import PARTITION_BIOS_GRUB
 
 from pyanaconda import iutil
-from pyanaconda.storage.devicelibs import mdraid
+from blivet.devicelibs import mdraid
 from pyanaconda.isys import sync, getMacAddress
 from pyanaconda.product import productName
 from pyanaconda.flags import flags
 from pyanaconda.constants import *
-from pyanaconda.storage.errors import StorageError
-from pyanaconda.storage.fcoe import fcoe
+from blivet.errors import StorageError
+from blivet.fcoe import fcoe
 import pyanaconda.network
-from pyanaconda.storage import platform
+from blivet import platform
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
@@ -756,7 +756,7 @@ class BootLoader(object):
 
             Keyword Arguments:
 
-                storage - a pyanaconda.storage.Storage instance
+                storage - a blivet.Storage instance
 
             All other arguments are expected to have a dracutSetupArgs()
             method.
@@ -774,7 +774,7 @@ class BootLoader(object):
         #
 
         # storage
-        from pyanaconda.storage.devices import NetworkStorageDevice
+        from blivet.devices import NetworkStorageDevice
         dracut_devices = [storage.rootDevice]
         if self.stage2_device != storage.rootDevice:
             dracut_devices.append(self.stage2_device)
diff --git a/pyanaconda/exception.py b/pyanaconda/exception.py
index 291adbc..f053c0d 100644
--- a/pyanaconda/exception.py
+++ b/pyanaconda/exception.py
@@ -32,7 +32,7 @@ import signal
 import time
 from flags import flags
 import kickstart
-import storage.errors
+import blivet.errors
 from pyanaconda.constants import ROOT_PATH
 from gi.repository import GLib
 
@@ -73,7 +73,7 @@ class AnacondaExceptionHandler(ExceptionHandler):
                                                                   obj)
             return False
 
-        if issubclass(ty, storage.errors.StorageError) and value.hardware_fault:
+        if issubclass(ty, blivet.errors.StorageError) and value.hardware_fault:
             hw_error_msg = _("The installation was stopped due to what "
                              "seems to be a problem with your hardware. "
                              "The exact error message is:\n\n%s.\n\n "
diff --git a/pyanaconda/image.py b/pyanaconda/image.py
index 6786082..c77587b 100644
--- a/pyanaconda/image.py
+++ b/pyanaconda/image.py
@@ -19,12 +19,12 @@
 
 import isys
 import os, os.path, stat, sys
-from pyanaconda.storage import util
 from constants import *
 
 from errors import *
 
-import pyanaconda.storage.arch
+import blivet.util
+import blivet.arch
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
@@ -32,7 +32,7 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
 import logging
 log = logging.getLogger("anaconda")
 
-_arch = pyanaconda.storage.arch.getArch()
+_arch = blivet.arch.getArch()
 
 def findFirstIsoImage(path):
     """
@@ -62,12 +62,12 @@ def findFirstIsoImage(path):
 
         log.debug("mounting %s on /mnt/install/cdimage", what)
         try:
-            util.mount(what, "/mnt/install/cdimage", fstype="iso9660", options="ro")
+            blivet.util.mount(what, "/mnt/install/cdimage", fstype="iso9660", options="ro")
         except OSError:
             continue
 
         if not os.access("/mnt/install/cdimage/.discinfo", os.R_OK):
-            util.umount("/mnt/install/cdimage")
+            blivet.util.umount("/mnt/install/cdimage")
             continue
 
         log.debug("Reading .discinfo")
@@ -81,14 +81,14 @@ def findFirstIsoImage(path):
         if discArch != arch:
             log.warning("findFirstIsoImage: architectures mismatch: %s, %s" %
                         (discArch, arch))
-            util.umount("/mnt/install/cdimage")
+            blivet.util.umount("/mnt/install/cdimage")
             continue
 
         # If there's no repodata, there's no point in trying to
         # install from it.
         if not os.access("/mnt/install/cdimage/repodata", os.R_OK):
             log.warning("%s doesn't have repodata, skipping" %(what,))
-            util.umount("/mnt/install/cdimage")
+            blivet.util.umount("/mnt/install/cdimage")
             continue
 
         # warn user if images appears to be wrong size
@@ -99,7 +99,7 @@ def findFirstIsoImage(path):
                 raise exn
 
         log.info("Found disc at %s" % fn)
-        util.umount("/mnt/install/cdimage")
+        blivet.util.umount("/mnt/install/cdimage")
         return fn
 
     return None
@@ -152,7 +152,7 @@ def mountImageDirectory(method, storage):
 
         while True:
             try:
-                util.mount(url, ISO_DIR, fstype="nfs", options=method.options)
+                blivet.util.mount(url, ISO_DIR, fstype="nfs", options=method.options)
             except OSError as e:
                 log.error("couldn't mount ISO source directory: %s" % e)
                 exn = MediaMountError(str(e))
@@ -175,7 +175,7 @@ def mountImage(isodir, tree):
             image = os.path.normpath("%s/%s" % (isodir, image))
 
         try:
-            util.mount(image, tree, fstype = 'iso9660', options="ro")
+            blivet.util.mount(image, tree, fstype = 'iso9660', options="ro")
         except OSError:
             exn = MissingImageError()
             if errorHandler.cb(exn) == ERROR_RAISE:
@@ -214,7 +214,7 @@ def potentialHdisoSources(devicetree):
 
 def umountImage(tree):
     if os.path.ismount(tree):
-        util.umount(tree)
+        blivet.util.umount(tree)
 
 def unmountCD(dev):
     if not dev:
diff --git a/pyanaconda/install.py b/pyanaconda/install.py
index 6e3ee99..9a55a9c 100644
--- a/pyanaconda/install.py
+++ b/pyanaconda/install.py
@@ -21,7 +21,7 @@
 #
 
 from pyanaconda.constants import ROOT_PATH
-from pyanaconda.storage import turnOnFilesystems
+from blivet import turnOnFilesystems
 from pyanaconda.bootloader import writeBootLoader
 from pyanaconda.progress import progress_report
 from pyanaconda.users import createLuserConf, getPassAlgo, Users
diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
index 888d081..753de20 100644
--- a/pyanaconda/installclass.py
+++ b/pyanaconda/installclass.py
@@ -30,9 +30,9 @@ import types
 
 from constants import *
 from product import *
-from storage.partspec import *
-from storage.devicelibs import swap
-from storage.platform import platform
+from blivet.partspec import *
+from blivet.devicelibs import swap
+from blivet.platform import platform
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
diff --git a/pyanaconda/isys/__init__.py b/pyanaconda/isys/__init__.py
index 7d73836..7f4bcb4 100755
--- a/pyanaconda/isys/__init__.py
+++ b/pyanaconda/isys/__init__.py
@@ -37,7 +37,7 @@ import stat
 import posix
 import sys
 from pyanaconda import iutil
-from pyanaconda.storage import arch
+import blivet.arch
 import re
 import struct
 import dbus
@@ -71,7 +71,7 @@ NM_DEVICE_TYPE_ETHERNET = 1
 
 DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties"
 
-if arch.getArch() in ("sparc", "ppc64"):
+if blivet.arch.getArch() in ("sparc", "ppc64"):
     MIN_RAM = 768 * 1024
     GUI_INSTALL_EXTRA_RAM = 512 * 1024
 else:
@@ -255,7 +255,7 @@ def isPaeAvailable():
         return isPAE
 
     isPAE = False
-    if not arch.isX86():
+    if not blivet.arch.isX86():
         return isPAE
 
     f = open("/proc/cpuinfo", "r")
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index 0d5da28..a93c552 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -19,17 +19,18 @@
 #
 
 from pyanaconda.errors import ScriptError, errorHandler
-from storage.deviceaction import *
-from storage.devices import LUKSDevice
-from storage.devicelibs.lvm import getPossiblePhysicalExtents
-from storage.devicelibs.mpath import MultipathConfigWriter, MultipathTopology
-from storage.devicelibs import swap
-from storage.formats import getFormat
-from storage.partitioning import doPartitioning
-from storage.partitioning import growLVM
-import storage.iscsi
-import storage.fcoe
-import storage.zfcp
+from blivet.deviceaction import *
+from blivet.devices import LUKSDevice
+from blivet.devicelibs.lvm import getPossiblePhysicalExtents
+from blivet.devicelibs.mpath import MultipathConfigWriter, MultipathTopology
+from blivet.devicelibs import swap
+from blivet.formats import getFormat
+from blivet.partitioning import doPartitioning
+from blivet.partitioning import growLVM
+import blivet.iscsi
+import blivet.fcoe
+import blivet.zfcp
+import blivet.arch
 
 import glob
 import iutil
@@ -43,7 +44,6 @@ import shlex
 import sys
 import urlgrabber
 import pykickstart.commands as commands
-from pyanaconda.storage import arch
 from pyanaconda import keyboard
 from pyanaconda import ntp
 from pyanaconda import timezone
@@ -244,7 +244,7 @@ class Authconfig(commands.authconfig.FC3_Authconfig):
 
 class AutoPart(commands.autopart.F18_AutoPart):
     def execute(self, storage, ksdata, instClass):
-        from pyanaconda.storage.partitioning import doAutoPartition
+        from blivet.partitioning import doAutoPartition
 
         if not self.autopart:
             return
@@ -451,7 +451,7 @@ class Fcoe(commands.fcoe.F13_Fcoe):
         if fc.nic not in isys.getDeviceProperties():
             raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent nic %s in fcoe command" % fc.nic)
 
-        storage.fcoe.fcoe().addSan(nic=fc.nic, dcb=fc.dcb, auto_vlan=True)
+        blivet.fcoe.fcoe().addSan(nic=fc.nic, dcb=fc.dcb, auto_vlan=True)
 
         return fc
 
@@ -546,7 +546,7 @@ class Iscsi(commands.iscsi.F17_Iscsi):
             if tg.iface not in active_ifaces:
                 raise KickstartValueError, formatErrorMsg(self.lineno, msg="network interface %s required by iscsi %s target is not up" % (tg.iface, tg.target))
 
-        mode = storage.iscsi.iscsi().mode
+        mode = blivet.iscsi.iscsi().mode
         if mode == "none":
             if tg.iface:
                 storage.iscsi.iscsi().create_interfaces(active_ifaces)
@@ -555,7 +555,7 @@ class Iscsi(commands.iscsi.F17_Iscsi):
             raise KickstartValueError, formatErrorMsg(self.lineno, msg="iscsi --iface must be specified (binding used) either for all targets or for none")
 
         try:
-            storage.iscsi.iscsi().addTarget(tg.ipaddr, tg.port, tg.user,
+            blivet.iscsi.iscsi().addTarget(tg.ipaddr, tg.port, tg.user,
                                             tg.password, tg.user_in,
                                             tg.password_in,
                                             target=tg.target,
@@ -573,7 +573,7 @@ class IscsiName(commands.iscsiname.FC6_IscsiName):
     def parse(self, args):
         retval = commands.iscsiname.FC6_IscsiName.parse(self, args)
 
-        storage.iscsi.iscsi().initiator = self.iscsiname
+        blivet.iscsi.iscsi().initiator = self.iscsiname
         return retval
 
 class Lang(commands.lang.FC3_Lang):
@@ -849,7 +849,7 @@ class PartitionData(commands.partition.F18_PartData):
             if self.onPart:
                 ksdata.onPart[kwargs["name"]] = self.onPart
         elif self.mountpoint == "/boot/efi":
-            if arch.isMactel():
+            if blivet.arch.isMactel():
                 type = "hfs+"
             else:
                 type = "EFI System Partition"
@@ -1288,7 +1288,7 @@ class ZFCP(commands.zfcp.F14_ZFCP):
     def parse(self, args):
         fcp = commands.zfcp.F14_ZFCP.parse(self, args)
         try:
-            storage.zfcp.ZFCP().addFCP(fcp.devnum, fcp.wwpn, fcp.fcplun)
+            blivet.zfcp.ZFCP().addFCP(fcp.devnum, fcp.wwpn, fcp.fcplun)
         except ValueError as e:
             log.warning(str(e))
 
@@ -1471,9 +1471,9 @@ def parseKickstart(f):
     # We need this so all the /dev/disk/* stuff is set up before parsing.
     udev_trigger(subsystem="block", action="change")
     # So that drives onlined by these can be used in the ks file
-    storage.iscsi.iscsi().startup()
-    storage.fcoe.fcoe().startup()
-    storage.zfcp.ZFCP().startup()
+    blivet.iscsi.iscsi().startup()
+    blivet.fcoe.fcoe().startup()
+    blivet.zfcp.ZFCP().startup()
     # Note we do NOT call dasd.startup() here, that does not online drives, but
     # only checks if they need formatting, which requires zerombr to be known
     detect_multipaths()
diff --git a/pyanaconda/network.py b/pyanaconda/network.py
index 1f2bf19..1c67625 100644
--- a/pyanaconda/network.py
+++ b/pyanaconda/network.py
@@ -39,8 +39,8 @@ import re
 from flags import flags
 from simpleconfig import IfcfgFile
 import urlgrabber.grabber
-from pyanaconda.storage.devices import FcoeDiskDevice, iScsiDiskDevice
-from pyanaconda.storage import arch
+from blivet.devices import FcoeDiskDevice, iScsiDiskDevice
+import blivet.arch
 
 import gettext
 _ = lambda x: gettext.ldgettext("anaconda", x)
@@ -272,7 +272,7 @@ class NetworkDevice(IfcfgFile):
     def __str__(self):
         s = ""
         keys = self.info.keys()
-        if arch.isS390() and ("HWADDR" in keys):
+        if blivet.arch.isS390() and ("HWADDR" in keys):
             keys.remove("HWADDR")
         # make sure we include autoneg in the ethtool line
         if 'ETHTOOL_OPTS' in keys:
@@ -597,7 +597,7 @@ def dracutBootArguments(ifcfg, storage_ipaddr, hostname=None):
 
     nettype = ifcfg.get("NETTYPE")
     subchannels = ifcfg.get("SUBCHANNELS")
-    if arch.isS390() and nettype and subchannels:
+    if blivet.arch.isS390() and nettype and subchannels:
         znet = "rd.znet=%s,%s" % (nettype, subchannels)
         options = ifcfg.get("OPTIONS").strip("'\"")
         if options:
diff --git a/pyanaconda/packaging/__init__.py b/pyanaconda/packaging/__init__.py
index 5624745..1cc9e7f 100644
--- a/pyanaconda/packaging/__init__.py
+++ b/pyanaconda/packaging/__init__.py
@@ -52,10 +52,10 @@ import logging
 log = logging.getLogger("packaging")
 
 from pyanaconda.errors import *
-from pyanaconda.storage.errors import StorageError
-from pyanaconda.storage import util
-from pyanaconda.storage import arch
-from pyanaconda.storage.platform import platform
+from blivet.errors import StorageError
+import blivet.util
+import blivet.arch
+from blivet.platform import platform
 #from pyanaconda.progress import progress
 
 from pyanaconda.product import productName, productVersion
@@ -129,7 +129,7 @@ def get_mount_device(mountpoint):
             break
 
     if mount_device and re.match(r'/dev/loop\d+$', mount_device):
-        from pyanaconda.storage.devicelibs import loop
+        from blivet.devicelibs import loop
         loop_name = os.path.basename(mount_device)
         mount_device = loop.get_backing_file(loop_name)
         log.debug("found backing file %s for loop device %s" % (mount_device,
@@ -484,7 +484,7 @@ class Payload(object):
                 return
             else:
                 try:
-                    util.umount(realMountpoint)
+                    blivet.util.umount(realMountpoint)
                 except Exception as e:
                     log.error(str(e))
                     log.info("umount failed -- mounting on top of it")
@@ -510,7 +510,7 @@ class Payload(object):
             else:
                 log.debug("%s already has something mounted on it" % mountpoint)
                 try:
-                    util.umount(mountpoint)
+                    blivet.util.umount(mountpoint)
                 except OSError as e:
                     log.error(str(e))
                     log.info("umount failed -- mounting on top of it")
@@ -519,7 +519,7 @@ class Payload(object):
         url = "%s:%s" % (server, path)
 
         try:
-            util.mount(url, mountpoint, fstype="nfs", options=options)
+            blivet.util.mount(url, mountpoint, fstype="nfs", options=options)
         except OSError as e:
             raise PayloadSetupError(str(e))
 
@@ -655,7 +655,7 @@ class PackagePayload(Payload):
             kernels.insert(0, "kernel-PAE")
 
         # most ARM systems use platform-specific kernels
-        if arch.isARM():
+        if blivet.arch.isARM():
             if platform.armMachine is not None:
                 kernels = ["kernel-%s" % platform.armMachine]
 
@@ -721,7 +721,7 @@ def write_txmbrs(payload, filename):
 if __name__ == "__main__":
     import os
     import sys
-    import pyanaconda.storage as _storage
+    import blivet
     from pykickstart.version import makeVersion
     from pyanaconda.packaging.yumpayload import YumPayload
 
@@ -736,7 +736,7 @@ if __name__ == "__main__":
     #ksdata.method.url = "http://dl.fedoraproject.org/pub/fedora/linux/development/17/x86_64/os/"
 
     # set up storage
-    storage = _storage.Storage(data=ksdata)
+    storage = blivet.Blivet(ksdata=ksdata)
     storage.reset()
 
     # set up the payload
diff --git a/pyanaconda/packaging/livepayload.py b/pyanaconda/packaging/livepayload.py
index 43f9871..1dddd70 100644
--- a/pyanaconda/packaging/livepayload.py
+++ b/pyanaconda/packaging/livepayload.py
@@ -46,8 +46,8 @@ log = logging.getLogger("anaconda")
 
 from pyanaconda.errors import *
 from pyanaconda import progress
-from pyanaconda.storage.size import Size
-from pyanaconda.storage import util
+from blivet.size import Size
+import blivet.util
 from pyanaconda.threads import threadMgr, AnacondaThread
 
 import gettext
@@ -64,7 +64,7 @@ class LiveImagePayload(ImagePayload):
             exn = PayloadSetupError("%s is not a valid block device" % (self.data.method.partition,))
             if errorHandler.cb(exn) == ERROR_RAISE:
                 raise exn
-        util.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro")
+        blivet.util.mount(osimg.path, INSTALL_TREE, fstype="auto", options="ro")
 
     def preInstall(self, packages=None, groups=None):
         """ Perform pre-installation tasks. """
@@ -130,7 +130,7 @@ class LiveImagePayload(ImagePayload):
     def postInstall(self):
         """ Perform post-installation tasks. """
         progress.send_message(_("Performing post-install setup tasks"))
-        util.umount(INSTALL_TREE)
+        blivet.util.umount(INSTALL_TREE)
 
         super(LiveImagePayload, self).postInstall()
         self._recreateInitrds()
diff --git a/pyanaconda/packaging/yumpayload.py b/pyanaconda/packaging/yumpayload.py
index 43feebe..83461b1 100644
--- a/pyanaconda/packaging/yumpayload.py
+++ b/pyanaconda/packaging/yumpayload.py
@@ -73,9 +73,9 @@ from pyanaconda.flags import flags
 from pyanaconda import iutil
 from pyanaconda.iutil import ProxyString, ProxyStringError
 from pyanaconda.network import hasActiveNetDev
-from pyanaconda.storage.size import Size
-from pyanaconda.storage import util
-from pyanaconda.storage import arch
+from blivet.size import Size
+import blivet.util
+import blivet.arch
 
 from pyanaconda.image import opticalInstallMedia
 from pyanaconda.image import mountImage
@@ -137,7 +137,7 @@ class YumPayload(PackagePayload):
                get_mount_device(INSTALL_TREE) == self.install_device.path:
                 self.install_device.teardown(recursive=True)
             else:
-                util.umount(INSTALL_TREE)
+                blivet.util.umount(INSTALL_TREE)
 
         if os.path.ismount(ISO_DIR) and not flags.testing:
             if self.install_device and \
@@ -150,7 +150,7 @@ class YumPayload(PackagePayload):
             # Commenting out the below is a hack for F18.  FIXME
             #else:
             #    # NFS
-            #    util.umount(ISO_DIR)
+            #    blivet.util.umount(ISO_DIR)
 
         self.install_device = None
 
@@ -835,7 +835,7 @@ reposdir=%s
 
         if mountpoint and os.path.ismount(mountpoint):
             try:
-                util.umount(mountpoint, removeDir=False)
+                blivet.util.umount(mountpoint)
             except SystemError as e:
                 log.error("failed to unmount nfs repo %s: %s" % (mountpoint, e))
 
@@ -1502,7 +1502,7 @@ class RPMCallback(object):
 
         self.total_actions = 0
         self.completed_actions = None   # will be set to 0 when starting tx
-        self.base_arch = arch.getArch()
+        self.base_arch = blivet.arch.getArch()
 
     def _get_txmbr(self, key):
         """ Return a (name, TransactionMember) tuple from cb key. """
diff --git a/pyanaconda/rescue.py b/pyanaconda/rescue.py
index 9b3be6d..c6750bf 100644
--- a/pyanaconda/rescue.py
+++ b/pyanaconda/rescue.py
@@ -28,8 +28,8 @@ from flags import flags
 import sys
 import os
 import isys
-from storage import mountExistingSystem
-from storage.errors import StorageError
+from blivet import mountExistingSystem
+from blivet.errors import StorageError
 from installinterfacebase import InstallInterfaceBase
 import iutil
 import shutil
@@ -192,7 +192,7 @@ def runShell(screen = None, msg=""):
         screen.finish()
 
 def doRescue(rescue_mount, ksdata):
-    import storage
+    import blivet
 
     for file in [ "services", "protocols", "group", "joe", "man.config",
                   "nsswitch.conf", "selinux", "mke2fs.conf" ]:
@@ -242,9 +242,9 @@ def doRescue(rescue_mount, ksdata):
 
             break
 
-    sto = storage.Storage(ksdata)
-    storage.storageInitialize(sto, ksdata, [])
-    roots = storage.findExistingInstallations(sto.devicetree)
+    sto = blivet.Blivet(ksdata=ksdata)
+    blivet.storageInitialize(sto, ksdata, [])
+    roots = blivet.findExistingInstallations(sto.devicetree)
 
     if not roots:
         root = None
diff --git a/pyanaconda/storage/Makefile.am b/pyanaconda/storage/Makefile.am
deleted file mode 100644
index 7347694..0000000
--- a/pyanaconda/storage/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# storage/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@redhat.com>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storagedir = $(pkgpyexecdir)/storage
-storage_PYTHON = *.py
-
-SUBDIRS = devicelibs formats
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py
deleted file mode 100644
index bc973e3..0000000
--- a/pyanaconda/storage/__init__.py
+++ /dev/null
@@ -1,3533 +0,0 @@
-# __init__.py
-# Entry point for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-##
-## Default stub values for installer-specific stuff that gets set up in
-## enable_installer_mode.
-##
-isys = None
-ROOT_PATH = '/'
-shortProductName = ''
-bootLoaderError = Exception
-
-import os
-import time
-import stat
-import errno
-import sys
-import statvfs
-import copy
-
-import nss.nss
-import parted
-
-from pykickstart.constants import *
-
-from storage_log import log_method_call
-from errors import *
-from devices import *
-from devicetree import DeviceTree
-from deviceaction import *
-from formats import getFormat
-from formats import get_device_format_class
-from formats import get_default_filesystem_type
-from devicelibs.dm import name_from_dm_node
-from devicelibs.crypto import generateBackupPassphrase
-from devicelibs.mpath import MultipathConfigWriter
-from devicelibs.edd import get_edd_dict
-from devicelibs.mdraid import get_member_space
-from devicelibs.mdraid import raidLevelString
-from devicelibs.lvm import get_pv_space
-from .partitioning import SameSizeSet
-from .partitioning import TotalSizeSet
-from .partitioning import doPartitioning
-from udev import *
-import iscsi
-import fcoe
-import zfcp
-import dasd
-import util
-import arch
-from flags import flags
-from platform import platform as _platform
-
-import shelve
-import contextlib
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def enable_installer_mode():
-    global isys
-    global ROOT_PATH
-    global shortProductName
-    global get_bootloader
-    global BootLoaderError
-
-    from pyanaconda import isys
-    from pyanaconda.constants import ROOT_PATH
-    from pyanaconda.constants import shortProductName
-    from pyanaconda.bootloader import get_bootloader
-    from pyanaconda.bootloader import BootLoaderError
-
-    flags.installer_mode = True
-
-DEVICE_TYPE_LVM = 0
-DEVICE_TYPE_MD = 1
-DEVICE_TYPE_PARTITION = 2
-DEVICE_TYPE_BTRFS = 3
-DEVICE_TYPE_DISK = 4
-
-def getDeviceType(device):
-    device_types = {"partition": DEVICE_TYPE_PARTITION,
-                    "lvmlv": DEVICE_TYPE_LVM,
-                    "btrfs subvolume": DEVICE_TYPE_BTRFS,
-                    "btrfs volume": DEVICE_TYPE_BTRFS,
-                    "mdarray": DEVICE_TYPE_MD}
-
-    use_dev = device
-    if isinstance(device, LUKSDevice):
-        use_dev = device.slave
-
-    if use_dev.isDisk:
-        device_type = DEVICE_TYPE_DISK
-    else:
-        device_type = device_types.get(use_dev.type)
-
-    return device_type
-
-def getRAIDLevel(device):
-    # TODO: move this into StorageDevice
-    use_dev = device
-    if isinstance(device, LUKSDevice):
-        use_dev = device.slave
-
-    # TODO: lvm and perhaps pulling raid level from md pvs
-    raid_level = None
-    if hasattr(use_dev, "level"):
-        raid_level = raidLevelString(use_dev.level)
-    elif hasattr(use_dev, "dataLevel"):
-        raid_level = use_dev.dataLevel or "single"
-    elif hasattr(use_dev, "volume"):
-        raid_level = use_dev.volume.dataLevel or "single"
-
-    return raid_level
-
-def storageInitialize(storage, ksdata, protected):
-    from pyanaconda.flags import flags as anaconda_flags
-    flags.update_from_anaconda_flags(anaconda_flags)
-
-    storage.shutdown()
-
-    # touch /dev/.in_sysinit so that /lib/udev/rules.d/65-md-incremental.rules
-    # does not mess with any mdraid sets
-    open("/dev/.in_sysinit", "w")
-
-    # XXX I don't understand why I have to do this, but this is needed to
-    #     populate the udev db
-    util.run_program(["udevadm", "control", "--property=ANACONDA=1"])
-    udev_trigger(subsystem="block", action="change")
-
-    # Before we set up the storage system, we need to know which disks to
-    # ignore, etc.  Luckily that's all in the kickstart data.
-    storage.config.update(ksdata)
-
-    lvm.lvm_vg_blacklist = []
-
-    # Set up the protected partitions list now.
-    if protected:
-        storage.config.protectedDevSpecs.extend(protected)
-        storage.reset()
-
-        if not flags.live_install and not storage.protectedDevices:
-            raise UnknownSourceDeviceError(protected)
-    else:
-        storage.reset()
-
-    # kickstart uses all the disks
-    if flags.automated_install:
-        if not ksdata.ignoredisk.onlyuse:
-            ksdata.ignoredisk.onlyuse = [d.name for d in storage.disks \
-                                         if d.name not in ksdata.ignoredisk.ignoredisk]
-            log.debug("onlyuse is now: %s" % (",".join(ksdata.ignoredisk.onlyuse)))
-
-def turnOnFilesystems(storage):
-    if not flags.installer_mode:
-        return
-
-    if (flags.live_install and not flags.image_install and not storage.fsset.active):
-        # turn off any swaps that we didn't turn on
-        # needed for live installs
-        util.run_program(["swapoff", "-a"])
-    storage.devicetree.teardownAll()
-
-    try:
-        storage.doIt()
-    except FSResizeError as e:
-        if os.path.exists("/tmp/resize.out"):
-            details = open("/tmp/resize.out", "r").read()
-        else:
-            details = e.args[1]
-
-        if errorHandler.cb(e, e.args[0], details=details) == ERROR_RAISE:
-            raise
-    except Exception as e:
-        raise
-
-    storage.turnOnSwap()
-    # FIXME:  For livecd, skipRoot needs to be True.
-    storage.mountFilesystems(raiseErrors=False,
-                             readOnly=False,
-                             skipRoot=False)
-    writeEscrowPackets(storage)
-
-def writeEscrowPackets(storage):
-    escrowDevices = filter(lambda d: d.format.type == "luks" and \
-                                     d.format.escrow_cert,
-                           storage.devices)
-
-    if not escrowDevices:
-        return
-
-    log.debug("escrow: writeEscrowPackets start")
-
-    nss.nss.nss_init_nodb() # Does nothing if NSS is already initialized
-
-    backupPassphrase = generateBackupPassphrase()
-    try:
-        for device in escrowDevices:
-            log.debug("escrow: device %s: %s" %
-                      (repr(device.path), repr(device.format.type)))
-            device.format.escrow(ROOT_PATH + "/root",
-                                 backupPassphrase)
-
-    except (IOError, RuntimeError) as e:
-        # TODO: real error handling
-        log.error("failed to store encryption key: %s" % e)
-
-    log.debug("escrow: writeEscrowPackets done")
-
-
-def undoEncryption(storage):
-    for device in storage.devicetree.getDevicesByType("luks/dm-crypt"):
-        if device.exists:
-            continue
-
-        slave = device.slave
-        format = device.format
-
-        # set any devices that depended on the luks device to now depend on
-        # the former slave device
-        for child in storage.devicetree.getChildren(device):
-            child.parents.remove(device)
-            device.removeChild()
-            child.parents.append(slave)
-
-        storage.devicetree.registerAction(ActionDestroyFormat(device))
-        storage.devicetree.registerAction(ActionDestroyDevice(device))
-        storage.devicetree.registerAction(ActionDestroyFormat(slave))
-        storage.devicetree.registerAction(ActionCreateFormat(slave, format))
-
-class StorageDiscoveryConfig(object):
-    def __init__(self):
-        # storage configuration variables
-        self.ignoreDiskInteractive = False
-        self.ignoredDisks = []
-        self.exclusiveDisks = []
-        self.clearPartType = None
-        self.clearPartDisks = []
-        self.clearPartDevices = []
-        self.initializeDisks = False
-        self.protectedDevSpecs = []
-        self.diskImages = {}
-        self.mpathFriendlyNames = True
-
-        # Whether clearPartitions removes scheduled/non-existent devices and
-        # disklabels depends on this flag.
-        self.clearNonExistent = False
-
-    def update(self, ksdata):
-        self.ignoredDisks = ksdata.ignoredisk.ignoredisk[:]
-        self.exclusiveDisks = ksdata.ignoredisk.onlyuse[:]
-        self.clearPartType = ksdata.clearpart.type
-        self.clearPartDisks = ksdata.clearpart.drives[:]
-        self.clearPartDevices = ksdata.clearpart.devices[:]
-        self.initializeDisks = ksdata.clearpart.initAll
-        self.zeroMbr = ksdata.zerombr.zerombr
-
-class Storage(object):
-    def __init__(self, data=None):
-        """ Create a Storage instance.
-
-            Keyword Arguments:
-
-                data        -   a pykickstart Handler instance
-        """
-        self.data = data
-        self._bootloader = None
-
-        self.config = StorageDiscoveryConfig()
-
-        # storage configuration variables
-        self.doAutoPart = False
-        self.clearPartChoice = None
-        self.encryptedAutoPart = False
-        self.autoPartType = AUTOPART_TYPE_LVM
-        self.encryptionPassphrase = None
-        self.encryptionCipher = None
-        self.escrowCertificates = {}
-        self.autoPartEscrowCert = None
-        self.autoPartAddBackupPassphrase = False
-        self.encryptionRetrofit = False
-        self.autoPartitionRequests = []
-        self.eddDict = {}
-
-        self.__luksDevs = {}
-        self.size_sets = []
-
-        self.iscsi = iscsi.iscsi()
-        self.fcoe = fcoe.fcoe()
-        self.zfcp = zfcp.ZFCP()
-        self.dasd = dasd.DASD()
-
-        self._nextID = 0
-        self.defaultFSType = get_default_filesystem_type()
-        self._dumpFile = "/tmp/storage.state"
-
-        # these will both be empty until our reset method gets called
-        self.devicetree = DeviceTree(conf=self.config,
-                                     passphrase=self.encryptionPassphrase,
-                                     luksDict=self.__luksDevs,
-                                     iscsi=self.iscsi,
-                                     dasd=self.dasd)
-        self.fsset = FSSet(self.devicetree)
-        self.roots = []
-        self.services = set()
-
-    def doIt(self):
-        self.devicetree.processActions()
-        self.doEncryptionPassphraseRetrofits()
-
-        # now set the boot partition's flag
-        if self.bootloader:
-            if self.bootloader.stage2_bootable:
-                boot = self.bootDevice
-            else:
-                boot = self.bootLoaderDevice
-
-            if boot.type == "mdarray":
-                bootDevs = boot.parents
-            else:
-                bootDevs = [boot]
-
-            for dev in bootDevs:
-                if hasattr(dev, "bootable"):
-                    # Dos labels can only have one partition marked as active
-                    # and unmarking ie the windows partition is not a good idea
-                    skip = False
-                    if dev.disk.format.partedDisk.type == "msdos":
-                        for p in dev.disk.format.partedDisk.partitions:
-                            if p.type == parted.PARTITION_NORMAL and \
-                               p.getFlag(parted.PARTITION_BOOT):
-                                skip = True
-                                break
-
-                    # GPT labeled disks should only have bootable set on the
-                    # EFI system partition (parted sets the EFI System GUID on
-                    # GPT partitions with the boot flag)
-                    if dev.disk.format.labelType == "gpt" and \
-                       dev.format.type != "efi":
-                           skip = True
-
-                    if skip:
-                         log.info("not setting boot flag on %s" % dev.name)
-                         continue
-                    # hfs+ partitions on gpt can't be marked bootable via
-                    # parted
-                    if dev.disk.format.partedDisk.type == "gpt" and \
-                            dev.format.type == "hfs+":
-                        log.info("not setting boot flag on hfs+ partition"
-                                 " %s" % dev.name)
-                        continue
-                    log.info("setting boot flag on %s" % dev.name)
-                    dev.bootable = True
-
-                    # Set the boot partition's name on disk labels that support it
-                    if dev.partedPartition.disk.supportsFeature(parted.DISK_TYPE_PARTITION_NAME):
-                        ped_partition = dev.partedPartition.getPedPartition()
-                        ped_partition.set_name(dev.format.name)
-
-                    dev.disk.setup()
-                    dev.disk.format.commitToDisk()
-
-        self.dumpState("final")
-
-    @property
-    def nextID(self):
-        id = self._nextID
-        self._nextID += 1
-        return id
-
-    def shutdown(self):
-        try:
-            self.devicetree.teardownAll()
-        except Exception as e:
-            log.error("failure tearing down device tree: %s" % e)
-
-    def reset(self, cleanupOnly=False):
-        """ Reset storage configuration to reflect actual system state.
-
-            This should rescan from scratch but not clobber user-obtained
-            information like passphrases, iscsi config, &c
-
-        """
-        # save passphrases for luks devices so we don't have to reprompt
-        self.encryptionPassphrase = None
-        for device in self.devices:
-            if device.format.type == "luks" and device.format.exists:
-                self.__luksDevs[device.format.uuid] = device.format._LUKS__passphrase
-
-        if self.data:
-            self.config.update(self.data)
-
-        if not flags.image_install:
-            self.iscsi.startup()
-            self.fcoe.startup()
-            self.zfcp.startup()
-            self.dasd.startup(None,
-                              self.config.exclusiveDisks,
-                              self.config.initializeDisks)
-        clearPartType = self.config.clearPartType # save this before overriding it
-        if self.dasd:
-            # Reset the internal dasd list (823534)
-            self.dasd.clear_device_list()
-
-        self.devicetree.reset(conf=self.config,
-                              passphrase=self.encryptionPassphrase,
-                              luksDict=self.__luksDevs,
-                              iscsi=self.iscsi,
-                              dasd=self.dasd)
-        self.devicetree.populate(cleanupOnly=cleanupOnly)
-        self.config.clearPartType = clearPartType # set it back
-        self.fsset = FSSet(self.devicetree)
-        self.eddDict = get_edd_dict(self.partitioned)
-        if self.bootloader:
-            # clear out bootloader attributes that refer to devices that are
-            # no longer in the tree
-            self.bootloader.stage1_disk = None
-            self.bootloader.stage1_device = None
-            self.bootloader.stage2_device = None
-
-        self.roots = findExistingInstallations(self.devicetree)
-
-        self.dumpState("initial")
-
-        self.updateBootLoaderDiskList()
-
-    @property
-    def unusedDevices(self):
-        used_devices = []
-        for root in self.roots:
-            for device in root.mounts.values() + root.swaps:
-                if device not in self.devices:
-                    continue
-
-                used_devices.extend(device.ancestors)
-
-        for new in [d for d in self.devicetree.leaves if not d.format.exists]:
-            if new in self.swaps or getattr(new.format, "mountpoint", None):
-                used_devices.extend(new.ancestors)
-
-        for device in self.partitions:
-            if getattr(device, "isLogical", False):
-                extended = device.disk.format.extendedPartition.path
-                used_devices.append(self.devicetree.getDeviceByPath(extended))
-
-        used = set(used_devices)
-        _all = set(self.devices)
-        return list(_all.difference(used))
-
-    @property
-    def devices(self):
-        """ A list of all the devices in the device tree. """
-        devices = self.devicetree.devices
-        devices.sort(key=lambda d: d.name)
-        return devices
-
-    @property
-    def disks(self):
-        """ A list of the disks in the device tree.
-
-            Ignored disks are not included, as are disks with no media present.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        disks = []
-        for device in self.devicetree.devices:
-            if device.isDisk:
-                if not device.mediaPresent:
-                    log.info("Skipping disk: %s: No media present" % device.name)
-                    continue
-                disks.append(device)
-        disks.sort(key=lambda d: d.name, cmp=self.compareDisks)
-        return disks
-
-    @property
-    def partitioned(self):
-        """ A list of the partitioned devices in the device tree.
-
-            Ignored devices are not included, nor disks with no media present.
-
-            Devices of types for which partitioning is not supported are also
-            not included.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        partitioned = []
-        for device in self.devicetree.devices:
-            if not device.partitioned:
-                continue
-
-            if not device.mediaPresent:
-                log.info("Skipping device: %s: No media present" % device.name)
-                continue
-
-            partitioned.append(device)
-
-        partitioned.sort(key=lambda d: d.name)
-        return partitioned
-
-    @property
-    def partitions(self):
-        """ A list of the partitions in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        partitions = self.devicetree.getDevicesByInstance(PartitionDevice)
-        partitions.sort(key=lambda d: d.name)
-        return partitions
-
-    @property
-    def vgs(self):
-        """ A list of the LVM Volume Groups in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        vgs = self.devicetree.getDevicesByType("lvmvg")
-        vgs.sort(key=lambda d: d.name)
-        return vgs
-
-    @property
-    def lvs(self):
-        """ A list of the LVM Logical Volumes in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        lvs = self.devicetree.getDevicesByType("lvmlv")
-        lvs.sort(key=lambda d: d.name)
-        return lvs
-
-    @property
-    def pvs(self):
-        """ A list of the LVM Physical Volumes in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        devices = self.devicetree.devices
-        pvs = [d for d in devices if d.format.type == "lvmpv"]
-        pvs.sort(key=lambda d: d.name)
-        return pvs
-
-    def unusedPVs(self, vg=None):
-        unused = []
-        for pv in self.pvs:
-            used = False
-            for _vg in self.vgs:
-                if _vg.dependsOn(pv) and _vg != vg:
-                    used = True
-                    break
-                elif _vg == vg:
-                    break
-            if not used:
-                unused.append(pv)
-        return unused
-
-    @property
-    def mdarrays(self):
-        """ A list of the MD arrays in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        arrays = self.devicetree.getDevicesByType("mdarray")
-        arrays.sort(key=lambda d: d.name)
-        return arrays
-
-    @property
-    def mdcontainers(self):
-        """ A list of the MD containers in the device tree. """
-        arrays = self.devicetree.getDevicesByType("mdcontainer")
-        arrays.sort(key=lambda d: d.name)
-        return arrays
-
-    @property
-    def mdmembers(self):
-        """ A list of the MD member devices in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        devices = self.devicetree.devices
-        members = [d for d in devices if d.format.type == "mdmember"]
-        members.sort(key=lambda d: d.name)
-        return members
-
-    def unusedMDMembers(self, array=None):
-        unused = []
-        for member in self.mdmembers:
-            used = False
-            for _array in self.mdarrays + self.mdcontainers:
-                if _array.dependsOn(member) and _array != array:
-                    used = True
-                    break
-                elif _array == array:
-                    break
-            if not used:
-                unused.append(member)
-        return unused
-
-    @property
-    def btrfsVolumes(self):
-        return sorted(self.devicetree.getDevicesByType("btrfs volume"),
-                      key=lambda d: d.name)
-
-    @property
-    def swaps(self):
-        """ A list of the swap devices in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        devices = self.devicetree.devices
-        swaps = [d for d in devices if d.format.type == "swap"]
-        swaps.sort(key=lambda d: d.name)
-        return swaps
-
-    @property
-    def protectedDevices(self):
-        devices = self.devicetree.devices
-        protected = [d for d in devices if d.protected]
-        protected.sort(key=lambda d: d.name)
-        return protected
-
-    @property
-    def liveImage(self):
-        """ The OS image used by live installs. """
-        return None
-
-    def shouldClear(self, device, **kwargs):
-        clearPartType = kwargs.get("clearPartType", self.config.clearPartType)
-        clearPartDisks = kwargs.get("clearPartDisks",
-                                    self.config.clearPartDisks)
-        clearPartDevices = kwargs.get("clearPartDevices",
-                                      self.config.clearPartDevices)
-
-        def empty_disk(device):
-            empty = True
-            if device.partitioned:
-                partitions = self.devicetree.getChildren(device)
-                empty = all([p.isMagic for p in partitions])
-            else:
-                empty = (device.format.type is None)
-
-            return empty
-
-        for disk in device.disks:
-            # this will not include disks with hidden formats like multipath
-            # and firmware raid member disks
-            if clearPartDisks and disk.name not in clearPartDisks:
-                return False
-
-        if not self.config.clearNonExistent:
-            if (device.isDisk and not device.format.exists) or \
-               (not device.isDisk and not device.exists):
-                return False
-
-        # the only devices we want to clear when clearPartType is
-        # CLEARPART_TYPE_NONE are uninitialized disks, or disks with no
-        # partitions, in clearPartDisks, and then only when we have been asked
-        # to initialize disks as needed
-        if clearPartType in [CLEARPART_TYPE_NONE, None]:
-            if not self.config.initializeDisks or not device.isDisk:
-                return False
-
-            if not empty_disk(device):
-                return False
-
-        if isinstance(device, PartitionDevice):
-            # Never clear the special first partition on a Mac disk label, as
-            # that holds the partition table itself.
-            # Something similar for the third partition on a Sun disklabel.
-            if device.isMagic:
-                return False
-
-            # We don't want to fool with extended partitions, freespace, &c
-            if not device.isPrimary and not device.isLogical:
-                return False
-
-            if clearPartType == CLEARPART_TYPE_LINUX and \
-               not device.format.linuxNative and \
-               not device.getFlag(parted.PARTITION_LVM) and \
-               not device.getFlag(parted.PARTITION_RAID) and \
-               not device.getFlag(parted.PARTITION_SWAP):
-                return False
-        elif device.isDisk:
-            if device.partitioned and clearPartType != CLEARPART_TYPE_ALL:
-                # if clearPartType is not CLEARPART_TYPE_ALL but we'll still be
-                # removing every partition from the disk, return True since we
-                # will want to be able to create a new disklabel on this disk
-                if not empty_disk(device):
-                    return False
-
-            # Never clear disks with hidden formats
-            if device.format.hidden:
-                return False
-
-            # When clearPartType is CLEARPART_TYPE_LINUX and a disk has non-
-            # linux whole-disk formatting, do not clear it. The exception is
-            # the case of an uninitialized disk when we've been asked to
-            # initialize disks as needed
-            if clearPartType == CLEARPART_TYPE_LINUX and \
-               not (self.config.initializeDisks and
-                    device.format.type is None) and \
-               not device.partitioned and not device.format.linuxNative:
-                return False
-
-        # Don't clear devices holding install media.
-        if device.protected:
-            return False
-
-        if clearPartType == CLEARPART_TYPE_LIST and \
-           device.name not in clearPartDevices:
-            return False
-
-        return True
-
-    def recursiveRemove(self, device):
-        log.debug("removing %s" % device.name)
-
-        # XXX is there any argument for not removing incomplete devices?
-        #       -- maybe some RAID devices
-        devices = self.deviceDeps(device)
-        while devices:
-            log.debug("devices to remove: %s" % ([d.name for d in devices],))
-            leaves = [d for d in devices if d.isleaf]
-            log.debug("leaves to remove: %s" % ([d.name for d in leaves],))
-            for leaf in leaves:
-                self.destroyDevice(leaf)
-                devices.remove(leaf)
-
-        if device.isDisk:
-            self.devicetree.registerAction(ActionDestroyFormat(device))
-        else:
-            self.destroyDevice(device)
-
-    def clearPartitions(self):
-        """ Clear partitions and dependent devices from disks.
-
-            Arguments:
-
-                None
-
-            NOTES:
-
-                - Needs some error handling
-
-        """
-        # Sort partitions by descending partition number to minimize confusing
-        # things like multiple "destroy sda5" actions due to parted renumbering
-        # partitions. This can still happen through the UI but it makes sense to
-        # avoid it where possible.
-        partitions = sorted(self.partitions,
-                            key=lambda p: p.partedPartition.number,
-                            reverse=True)
-        for part in partitions:
-            log.debug("clearpart: looking at %s" % part.name)
-            if not self.shouldClear(part):
-                continue
-
-            self.recursiveRemove(part)
-            log.debug("partitions: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions])
-
-        # now remove any empty extended partitions
-        self.removeEmptyExtendedPartitions()
-
-        # ensure all disks have appropriate disklabels
-        for disk in self.disks:
-            if not self.shouldClear(disk):
-                continue
-
-            log.debug("clearpart: initializing %s" % disk.name)
-            self.initializeDisk(disk)
-
-        self.updateBootLoaderDiskList()
-
-    def initializeDisk(self, disk):
-        """ (Re)initialize a disk by creating a disklabel on it.
-
-            The disk should not contain any partitions except perhaps for a
-            magic partitions on mac and sun disklabels.
-        """
-        # first, remove magic mac/sun partitions from the parted Disk
-        if disk.partitioned:
-            magic_partitions = {"mac": 1, "sun": 3}
-            if disk.format.labelType in magic_partitions:
-                number = magic_partitions[disk.format.labelType]
-                # remove the magic partition
-                for part in disk.format.partitions:
-                    if part.disk == disk and part.partedPartition.number == number:
-                        log.debug("removing %s" % part.name)
-                        # We can't schedule the magic partition for removal
-                        # because parted will not allow us to remove it from the
-                        # disk. Still, we need it out of the devicetree.
-                        self.devicetree._removeDevice(part, moddisk=False)
-
-        if disk.partitioned and disk.format.partitions:
-            raise ValueError("cannot initialize a disk that has partitions")
-
-        # remove existing formatting from the disk
-        destroy_action = ActionDestroyFormat(disk)
-        self.devicetree.registerAction(destroy_action)
-
-        labelType = _platform.bestDiskLabelType(disk)
-
-        # create a new disklabel on the disk
-        newLabel = getFormat("disklabel", device=disk.path,
-                             labelType=labelType)
-        create_action = ActionCreateFormat(disk, format=newLabel)
-        self.devicetree.registerAction(create_action)
-
-    def removeEmptyExtendedPartitions(self):
-        for disk in self.partitioned:
-            log.debug("checking whether disk %s has an empty extended" % disk.name)
-            extended = disk.format.extendedPartition
-            logical_parts = disk.format.logicalPartitions
-            log.debug("extended is %s ; logicals is %s" % (extended, [p.getDeviceNodeName() for p in logical_parts]))
-            if extended and not logical_parts:
-                log.debug("removing empty extended partition from %s" % disk.name)
-                extended_name = devicePathToName(extended.getDeviceNodeName())
-                extended = self.devicetree.getDeviceByName(extended_name)
-                self.destroyDevice(extended)
-
-    def getFreeSpace(self, disks=None, clearPartType=None):
-        """ Return a dict with free space info for each disk.
-
-            The dict values are 2-tuples: (disk_free, fs_free). fs_free is
-            space available by shrinking filesystems. disk_free is space not
-            allocated to any partition.
-
-            disks and clearPartType allow specifying a set of disks other than
-            self.disks and a clearPartType value other than
-            self.config.clearPartType.
-        """
-        from size import Size
-        if disks is None:
-            disks = self.disks
-
-        if clearPartType is None:
-            clearPartType = self.config.clearPartType
-
-        free = {}
-        for disk in disks:
-            should_clear = self.shouldClear(disk, clearPartType=clearPartType,
-                                            clearPartDisks=[disk.name])
-            if should_clear:
-                free[disk.name] = (Size(spec="%f mb" % disk.size), 0)
-                continue
-
-            disk_free = 0
-            fs_free = 0
-            if disk.partitioned:
-                disk_free = disk.format.free
-                for partition in [p for p in self.partitions if p.disk == disk]:
-                    # only check actual filesystems since lvm &c require a bunch of
-                    # operations to translate free filesystem space into free disk
-                    # space
-                    should_clear = self.shouldClear(partition,
-                                                    clearPartType=clearPartType,
-                                                    clearPartDisks=[disk.name])
-                    if should_clear:
-                        disk_free += partition.size
-                    elif hasattr(partition.format, "free"):
-                        fs_free += partition.format.free
-            elif hasattr(disk.format, "free"):
-                fs_free = disk.format.free
-            elif disk.format.type is None:
-                disk_free = disk.size
-
-            free[disk.name] = (Size(spec="%f mb" % disk_free),
-                               Size(spec="%f mb" % fs_free))
-
-        return free
-
-    @property
-    def names(self):
-        return self.devicetree.names
-
-    def exceptionDisks(self):
-        """ Return a list of removable devices to save exceptions to.
-
-            FIXME: This raises the problem that the device tree can be
-                   in a state that does not reflect that actual current
-                   state of the system at any given point.
-
-                   We need a way to provide direct scanning of disks,
-                   partitions, and filesystems without relying on the
-                   larger objects' correctness.
-
-                   Also, we need to find devices that have just been made
-                   available for the purpose of storing the exception
-                   report.
-        """
-        # When a usb is connected from before the start of the installation,
-        # it is not correctly detected.
-        udev_trigger(subsystem="block", action="change")
-        self.reset()
-
-        dests = []
-
-        for disk in self.disks:
-            if not disk.removable and \
-                    disk.format is not None  and \
-                    disk.format.mountable:
-                dests.append([disk.path, disk.name])
-
-        for part in self.partitions:
-            if not part.disk.removable:
-                continue
-
-            elif part.partedPartition.active and \
-                    not part.partedPartition.getFlag(parted.PARTITION_RAID) and \
-                    not part.partedPartition.getFlag(parted.PARTITION_LVM) and \
-                    part.format is not None and part.format.mountable:
-                dests.append([part.path, part.name])
-
-        return dests
-
-    def deviceImmutable(self, device, ignoreProtected=False):
-        """ Return any reason the device cannot be modified/removed.
-
-            Return False if the device can be removed.
-
-            Devices that cannot be removed include:
-
-                - protected partitions
-                - devices that are part of an md array or lvm vg
-                - extended partition containing logical partitions that
-                  meet any of the above criteria
-
-        """
-        if not isinstance(device, Device):
-            raise ValueError("arg1 (%s) must be a Device instance" % device)
-
-        if not ignoreProtected and device.protected and \
-           not getattr(device.format, "inconsistentVG", False):
-            return _("This partition is holding the data for the hard "
-                      "drive install.")
-        elif isinstance(device, PartitionDevice) and device.isProtected:
-            # LDL formatted DASDs always have one partition, you'd have to
-            # reformat the DASD in CDL mode to get rid of it
-            return _("You cannot delete a partition of a LDL formatted "
-                     "DASD.")
-        elif device.format.type == "mdmember":
-            for array in self.mdarrays + self.mdcontainers:
-                if array.dependsOn(device):
-                    if array.minor is not None:
-                        return _("This device is part of the RAID "
-                                 "device %s.") % (array.path,)
-                    else:
-                        return _("This device is part of a RAID device.")
-        elif device.format.type == "lvmpv":
-            if device.format.inconsistentVG:
-                return _("This device is part of an inconsistent LVM "
-                         "Volume Group.")
-            for vg in self.vgs:
-                if vg.dependsOn(device):
-                    if vg.name is not None:
-                        return _("This device is part of the LVM "
-                                 "volume group '%s'.") % (vg.name,)
-                    else:
-                        return _("This device is part of a LVM volume "
-                                 "group.")
-        elif device.format.type == "luks":
-            try:
-                luksdev = self.devicetree.getChildren(device)[0]
-            except IndexError:
-                pass
-            else:
-                return self.deviceImmutable(luksdev)
-        elif isinstance(device, PartitionDevice) and device.isExtended:
-            reasons = {}
-            for dep in self.deviceDeps(device):
-                reason = self.deviceImmutable(dep)
-                if reason:
-                    reasons[dep.path] = reason
-            if reasons:
-                msg =  _("This device is an extended partition which "
-                         "contains logical partitions that cannot be "
-                         "deleted:\n\n")
-                for dev in reasons:
-                    msg += "%s: %s" % (dev, reasons[dev])
-                return msg
-
-        return False
-
-    def deviceDeps(self, device):
-        return self.devicetree.getDependentDevices(device)
-
-    def newPartition(self, *args, **kwargs):
-        """ Return a new PartitionDevice instance for configuring. """
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=kwargs.pop("mountpoint",
-                                                               None),
-                                         **kwargs.pop("fmt_args", {}))
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            name = "req%d" % self.nextID
-
-        if "weight" not in kwargs:
-            fmt = kwargs.get("format")
-            if fmt:
-                mountpoint = getattr(fmt, "mountpoint", None)
-
-                kwargs["weight"] = _platform.weight(mountpoint=mountpoint,
-                                                        fstype=fmt.type)
-
-
-        return PartitionDevice(name, *args, **kwargs)
-
-    def newMDArray(self, *args, **kwargs):
-        """ Return a new MDRaidArrayDevice instance for configuring. """
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=kwargs.pop("mountpoint",
-                                                               None),
-                                         **kwargs.pop("fmt_args", {}))
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-            safe_name = self.safeDeviceName(name)
-            if safe_name != name:
-                log.warning("using '%s' instead of specified name '%s'"
-                                % (safe_name, name))
-                name = safe_name
-        else:
-            swap = getattr(kwargs.get("format"), "type", None) == "swap"
-            mountpoint = getattr(kwargs.get("format"), "mountpoint", None)
-            name = self.suggestDeviceName(prefix=shortProductName,
-                                          swap=swap,
-                                          mountpoint=mountpoint)
-
-        return MDRaidArrayDevice(name, *args, **kwargs)
-
-    def newVG(self, *args, **kwargs):
-        """ Return a new LVMVolumeGroupDevice instance. """
-        pvs = kwargs.pop("parents", [])
-        for pv in pvs:
-            if pv not in self.devices:
-                raise ValueError("pv is not in the device tree")
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-            safe_name = self.safeDeviceName(name)
-            if safe_name != name:
-                log.warning("using '%s' instead of specified name '%s'"
-                                % (safe_name, name))
-                name = safe_name
-        else:
-            hostname = ""
-            if self.data and self.data.network.hostname is not None:
-                hostname = self.data.network.hostname
-
-            name = self.suggestContainerName(hostname=hostname)
-
-        if name in self.names:
-            raise ValueError("name already in use")
-
-        return LVMVolumeGroupDevice(name, pvs, *args, **kwargs)
-
-    def newLV(self, *args, **kwargs):
-        """ Return a new LVMLogicalVolumeDevice instance. """
-        vg = kwargs.get("parents", [None])[0]
-        mountpoint = kwargs.pop("mountpoint", None)
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=mountpoint,
-                                         **kwargs.pop("fmt_args", {}))
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-            # make sure the specified name is sensible
-            safe_vg_name = self.safeDeviceName(vg.name)
-            full_name = "%s-%s" % (safe_vg_name, name)
-            safe_name = self.safeDeviceName(full_name)
-            if safe_name != full_name:
-                new_name = safe_name[len(safe_vg_name)+1:]
-                log.warning("using '%s' instead of specified name '%s'"
-                                % (new_name, name))
-                name = new_name
-        else:
-            if kwargs.get("format") and kwargs["format"].type == "swap":
-                swap = True
-            else:
-                swap = False
-            name = self.suggestDeviceName(parent=vg,
-                                          swap=swap,
-                                          mountpoint=mountpoint)
-
-        if "%s-%s" % (vg.name, name) in self.names:
-            raise ValueError("name already in use")
-
-        return LVMLogicalVolumeDevice(name, *args, **kwargs)
-
-    def newBTRFS(self, *args, **kwargs):
-        """ Return a new BTRFSVolumeDevice or BRFSSubVolumeDevice. """
-        log.debug("newBTRFS: args = %s ; kwargs = %s" % (args, kwargs))
-        name = kwargs.pop("name", None)
-        if args:
-            name = args[0]
-
-        mountpoint = kwargs.pop("mountpoint", None)
-
-        fmt_args = kwargs.pop("fmt_args", {})
-        fmt_args.update({"mountpoint": mountpoint})
-
-        if kwargs.pop("subvol", False):
-            dev_class = BTRFSSubVolumeDevice
-            # make sure there's a valid parent device
-            parents = kwargs.get("parents", [])
-            if not parents or len(parents) != 1 or \
-               not isinstance(parents[0], BTRFSVolumeDevice):
-                raise ValueError("new btrfs subvols require a parent volume")
-
-            # set up the subvol name, using mountpoint if necessary
-            if not name:
-                # for btrfs this only needs to ensure the subvol name is not
-                # already in use within the parent volume
-                name = self.suggestDeviceName(mountpoint=mountpoint)
-            fmt_args["mountopts"] = "subvol=%s" % name
-            kwargs.pop("metaDataLevel", None)
-            kwargs.pop("dataLevel", None)
-        else:
-            dev_class = BTRFSVolumeDevice
-            # set up the volume label, using hostname if necessary
-            if not name:
-                hostname = ""
-                if self.data and self.data.network.hostname is not None:
-                    hostname = self.data.network.hostname
-
-                name = self.suggestContainerName(hostname=hostname)
-            if "label" not in fmt_args:
-                fmt_args["label"] = name
-
-        # discard fmt_type since it's btrfs always
-        kwargs.pop("fmt_type", None)
-
-        # this is to avoid auto-scheduled format create actions
-        device = dev_class(name, **kwargs)
-        device.format = getFormat("btrfs", **fmt_args)
-        return device
-
-    def newBTRFSSubVolume(self, *args, **kwargs):
-        kwargs["subvol"] = True
-        return self.newBTRFS(*args, **kwargs)
-
-    def createDevice(self, device):
-        """ Schedule creation of a device.
-
-            TODO: We could do some things here like assign the next
-                  available raid minor if one isn't already set.
-        """
-        self.devicetree.registerAction(ActionCreateDevice(device))
-        if device.format.type:
-            self.devicetree.registerAction(ActionCreateFormat(device))
-
-    def destroyDevice(self, device):
-        """ Schedule destruction of a device. """
-        if device.format.exists and device.format.type:
-            # schedule destruction of any formatting while we're at it
-            self.devicetree.registerAction(ActionDestroyFormat(device))
-
-        action = ActionDestroyDevice(device)
-        self.devicetree.registerAction(action)
-
-    def formatDevice(self, device, format):
-        """ Schedule formatting of a device. """
-        self.devicetree.registerAction(ActionDestroyFormat(device))
-        self.devicetree.registerAction(ActionCreateFormat(device, format))
-
-    def resetDevice(self, device):
-        """ Cancel all scheduled actions and reset formatting. """
-        actions = self.devicetree.findActions(device=device)
-        for action in reversed(actions):
-            self.devicetree.cancelAction(action)
-
-        # make sure any random overridden attributes are reset
-        device.format = copy.copy(device.originalFormat)
-
-    def resizeDevice(self, device, new_size):
-        classes = []
-        if device.resizable:
-            classes.append(ActionResizeDevice)
-
-        if device.format.resizable:
-            classes.append(ActionResizeFormat)
-
-        if not classes:
-            raise ValueError("device cannot be resized")
-
-        # if this is a shrink, schedule the format resize first
-        if new_size < device.size:
-            classes.reverse()
-
-        for action_class in classes:
-            self.devicetree.registerAction(action_class(device, new_size))
-
-    def formatByDefault(self, device):
-        """Return whether the device should be reformatted by default."""
-        formatlist = ['/boot', '/var', '/tmp', '/usr']
-        exceptlist = ['/home', '/usr/local', '/opt', '/var/www']
-
-        if not device.format.linuxNative:
-            return False
-
-        if device.format.mountable:
-            if not device.format.mountpoint:
-                return False
-
-            if device.format.mountpoint == "/" or \
-               device.format.mountpoint in formatlist:
-                return True
-
-            for p in formatlist:
-                if device.format.mountpoint.startswith(p):
-                    for q in exceptlist:
-                        if device.format.mountpoint.startswith(q):
-                            return False
-                    return True
-        elif device.format.type == "swap":
-            return True
-
-        # be safe for anything else and default to off
-        return False
-
-    def mustFormat(self, device):
-        """ Return a string explaining why the device must be reformatted.
-
-            Return None if the device need not be reformatted.
-        """
-        if device.format.mountable and device.format.mountpoint == "/":
-            return _("You must create a new filesystem on the root device.")
-
-        return None
-
-    def extendedPartitionsSupported(self):
-        """ Return whether any disks support extended partitions."""
-        for disk in self.partitioned:
-            if disk.format.partedDisk.supportsFeature(parted.DISK_TYPE_EXTENDED):
-                return True
-        return False
-
-    def safeDeviceName(self, name):
-        """ Convert a device name to something safe and return that.
-
-            LVM limits lv names to 128 characters. I don't know the limits for
-            the other various device types, so I'm going to pick a number so
-            that we don't have to have an entire fucking library to determine
-            device name limits.
-        """
-        max_len = 96    # No, you don't need longer names than this. Really.
-        tmp = name.strip()
-        tmp = tmp.replace("/", "_")
-        tmp = re.sub("[^0-9a-zA-Z._-]", "", tmp)
-        tmp = tmp.lstrip("_")
-
-        if len(tmp) > max_len:
-            tmp = tmp[:max_len]
-
-        return tmp
-
-    def suggestContainerName(self, hostname=None, prefix=""):
-        """ Return a reasonable, unused device name. """
-        if not prefix:
-            prefix = shortProductName
-
-        # try to create a device name incorporating the hostname
-        if hostname not in (None, "", 'localhost', 'localhost.localdomain'):
-            template = "%s_%s" % (prefix, hostname.split('.')[0].lower())
-            template = self.safeDeviceName(template)
-        else:
-            template = prefix
-
-        if flags.image_install:
-            template = "%s_image" % template
-
-        names = self.names
-        name = template
-        if name in names:
-            name = None
-            for i in range(100):
-                tmpname = "%s%02d" % (template, i,)
-                if tmpname not in names:
-                    name = tmpname
-                    break
-
-            if not name:
-                log.error("failed to create device name based on prefix "
-                          "'%s' and hostname '%s'" % (prefix, hostname))
-                raise RuntimeError("unable to find suitable device name")
-
-        return name
-
-    def suggestDeviceName(self, parent=None, swap=None,
-                                  mountpoint=None, prefix=""):
-        """ Return a suitable, unused name for a new logical volume. """
-        body = ""
-        if mountpoint:
-            if mountpoint == "/":
-                body = "root"
-            else:
-                body = mountpoint[1:].replace("/", "_")
-        elif swap:
-            body = "swap"
-
-        if prefix:
-            body = "_" + body
-
-        template = self.safeDeviceName(prefix + body)
-        names = self.names
-        name = template
-        def full_name(name, parent):
-            full = ""
-            if parent:
-                full = "%s-" % parent.name
-            full += name
-            return full
-
-        # also include names of any lvs in the parent for the case of the
-        # temporary vg in the lvm dialogs, which can contain lvs that are
-        # not yet in the devicetree and therefore not in self.names
-        if full_name(name, parent) in names or not body:
-            for i in range(100):
-                name = "%s%02d" % (template, i)
-                if full_name(name, parent) not in names:
-                    break
-                else:
-                    name = ""
-
-            if not name:
-                log.error("failed to create device name based on parent '%s', "
-                          "prefix '%s', mountpoint '%s', swap '%s'"
-                          % (parent.name, prefix, mountpoint, swap))
-                raise RuntimeError("unable to find suitable device name")
-
-        return name
-
-    def savePassphrase(self, device):
-        """ Save a device's LUKS passphrase in case of reset. """
-        passphrase = device.format._LUKS__passphrase
-        self.__luksDevs[device.format.uuid] = passphrase
-        self.devicetree._DeviceTree__luksDevs[device.format.uuid] = passphrase
-        self.devicetree._DeviceTree__passphrases.append(passphrase)
-
-    def doEncryptionPassphraseRetrofits(self):
-        """ Add the global passphrase to all preexisting LUKS devices.
-
-            This establishes a common passphrase for all encrypted devices
-            in the system so that users only have to enter one passphrase
-            during system boot.
-        """
-        if not self.encryptionRetrofit:
-            return
-
-        for device in self.devices:
-            if device.format.type == "luks" and \
-               device.format._LUKS__passphrase != self.encryptionPassphrase:
-                log.info("adding new passphrase to preexisting encrypted "
-                         "device %s" % device.path)
-                try:
-                    device.format.addPassphrase(self.encryptionPassphrase)
-                except CryptoError:
-                    log.error("failed to add new passphrase to existing "
-                              "device %s" % device.path)
-
-    def setupDiskImages(self):
-        self.devicetree.setDiskImages(self.config.diskImages)
-        self.devicetree.setupDiskImages()
-
-    @property
-    def fileSystemFreeSpace(self):
-        mountpoints = ["/", "/usr"]
-        free = 0
-        btrfs_volumes = []
-        for mountpoint in mountpoints:
-            device = self.mountpoints.get(mountpoint)
-            if not device:
-                continue
-
-            # don't count the size of btrfs volumes repeatedly when multiple
-            # subvolumes are present
-            if isinstance(device, BTRFSSubVolumeDevice):
-                if device.volume in btrfs_volumes:
-                    continue
-                else:
-                    btrfs_volumes.append(device.volume)
-
-            if device.format.exists:
-                free += device.format.free
-            else:
-                free += device.size
-
-        return free
-
-    def sanityCheck(self):
-        """ Run a series of tests to verify the storage configuration.
-
-            This function is called at the end of partitioning so that
-            we can make sure you don't have anything silly (like no /,
-            a really small /, etc).  Returns (errors, warnings) where
-            each is a list of strings.
-        """
-        warnings = []
-        errors = []
-
-        if not flags.installer_mode:
-            return (errors, warnings)
-
-        checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 384),
-                      ('/home', 100), ('/boot', 75)]
-        mustbeonlinuxfs = ['/', '/var', '/tmp', '/usr', '/home', '/usr/share', '/usr/lib']
-        mustbeonroot = ['/bin','/dev','/sbin','/etc','/lib','/root', '/mnt', 'lost+found', '/proc']
-
-        filesystems = self.mountpoints
-        root = self.fsset.rootDevice
-        swaps = self.fsset.swapDevices
-        try:
-            boot = self.bootDevice
-        except (DeviceError, AttributeError):
-            boot = None
-
-        if not root:
-            errors.append(_("You have not defined a root partition (/), "
-                            "which is required for installation of %s "
-                            "to continue.") % (productName,))
-
-        if root and root.size < 250:
-            warnings.append(_("Your root partition is less than 250 "
-                              "megabytes which is usually too small to "
-                              "install %s.") % (productName,))
-
-        # Prevent users from installing on s390x with (a) no /boot volume, (b) the
-        # root volume on LVM, and (c) the root volume not restricted to a single
-        # PV
-        # NOTE: There is not really a way for users to create a / volume
-        # restricted to a single PV.  The backend support is there, but there are
-        # no UI hook-ups to drive that functionality, but I do not personally
-        # care.  --dcantrell
-        if arch.isS390() and \
-           not self.mountpoints.has_key('/boot') and \
-           root.type == 'lvmlv' and not root.singlePV:
-            errors.append(_("This platform requires /boot on a dedicated "
-                            "partition or logical volume.  If you do not "
-                            "want a /boot volume, you must place / on a "
-                            "dedicated non-LVM partition."))
-
-        # FIXME: put a check here for enough space on the filesystems. maybe?
-
-        for (mount, size) in checkSizes:
-            if mount in filesystems and filesystems[mount].size < size:
-                warnings.append(_("Your %(mount)s partition is less than "
-                                  "%(size)s megabytes which is lower than "
-                                  "recommended for a normal %(productName)s "
-                                  "install.")
-                                % {'mount': mount, 'size': size,
-                                   'productName': productName})
-
-        for (mount, device) in filesystems.items():
-            problem = filesystems[mount].checkSize()
-            if problem < 0:
-                errors.append(_("Your %(mount)s partition is too small for %(format)s formatting "
-                                "(allowable size is %(minSize)d MB to %(maxSize)d MB)")
-                              % {"mount": mount, "format": device.format.name,
-                                 "minSize": device.minSize, "maxSize": device.maxSize})
-            elif problem > 0:
-                errors.append(_("Your %(mount)s partition is too large for %(format)s formatting "
-                                "(allowable size is %(minSize)d MB to %(maxSize)d MB)")
-                              % {"mount":mount, "format": device.format.name,
-                                 "minSize": device.minSize, "maxSize": device.maxSize})
-
-        # FIXME: this does not work, but probably should
-        """
-        usb_disks = []
-        firewire_disks = []
-        #for disk in self.disks:
-            if isys.driveUsesModule(disk.name, ["usb-storage", "ub"]):
-                usb_disks.append(disk)
-            elif isys.driveUsesModule(disk.name, ["sbp2", "firewire-sbp2"]):
-                firewire_disks.append(disk)
-
-        uses_usb = False
-        uses_firewire = False
-        for device in filesystems.values():
-            for disk in usb_disks:
-                if device.dependsOn(disk):
-                    uses_usb = True
-                    break
-
-            for disk in firewire_disks:
-                if device.dependsOn(disk):
-                    uses_firewire = True
-                    break
-
-        if uses_usb:
-            warnings.append(_("Installing on a USB device.  This may "
-                              "or may not produce a working system."))
-        if uses_firewire:
-            warnings.append(_("Installing on a FireWire device.  This may "
-                              "or may not produce a working system."))
-        """
-
-        if self.bootloader and not self.bootloader.skip_bootloader:
-            stage1 = self.bootloader.stage1_device
-            if not stage1:
-                errors.append(_("you have not created a bootloader stage1 "
-                                "target device"))
-            else:
-                self.bootloader.is_valid_stage1_device(stage1)
-                errors.extend(self.bootloader.errors)
-                warnings.extend(self.bootloader.warnings)
-
-            stage2 = self.bootloader.stage2_device
-            if not stage2:
-                errors.append(_("You have not created a bootable partition."))
-            else:
-                self.bootloader.is_valid_stage2_device(stage2)
-                errors.extend(self.bootloader.errors)
-                warnings.extend(self.bootloader.warnings)
-                if not self.bootloader.check():
-                    errors.extend(self.bootloader.errors)
-
-            #
-            # check that GPT boot disk on BIOS system has a BIOS boot partition
-            #
-            if _platform.weight(fstype="biosboot") and \
-               stage1 and stage1.isDisk and \
-               getattr(stage1.format, "labelType", None) == "gpt":
-                missing = True
-                for part in [p for p in self.partitions if p.disk == stage1]:
-                    if part.format.type == "biosboot":
-                        missing = False
-                        break
-
-                if missing:
-                    errors.append(_("Your BIOS-based system needs a special "
-                                    "partition to boot with %s's new "
-                                    "disk label format (GPT). To continue, "
-                                    "please create a 1MB 'BIOS Boot' type "
-                                    "partition.") % productName)
-
-        if not swaps:
-            from pyanaconda.storage.size import Size
-
-            installed = Size(spec="%s kb" % util.total_memory())
-            required = Size(spec="%s kb" % isys.EARLY_SWAP_RAM)
-
-            if installed < required:
-                errors.append(_("You have not specified a swap partition.  "
-                                "%(requiredMem)s MB of memory is required to continue installation "
-                                "without a swap partition, but you only have %(installedMem)s MB.")
-                              % {"requiredMem": int(required.convertTo(spec="MB")),
-                                 "installedMem": int(installed.convertTo(spec="MB"))})
-            else:
-                warnings.append(_("You have not specified a swap partition.  "
-                                  "Although not strictly required in all cases, "
-                                  "it will significantly improve performance "
-                                  "for most installations."))
-        no_uuid = [s for s in swaps if s.format.exists and not s.format.uuid]
-        if no_uuid:
-            warnings.append(_("At least one of your swap devices does not have "
-                              "a UUID, which is common in swap space created "
-                              "using older versions of mkswap. These devices "
-                              "will be referred to by device path in "
-                              "/etc/fstab, which is not ideal since device "
-                              "paths can change under a variety of "
-                              "circumstances. "))
-
-        for (mountpoint, dev) in filesystems.items():
-            if mountpoint in mustbeonroot:
-                errors.append(_("This mount point is invalid.  The %s directory must "
-                                "be on the / file system.") % mountpoint)
-
-            if mountpoint in mustbeonlinuxfs and (not dev.format.mountable or not dev.format.linuxNative):
-                errors.append(_("The mount point %s must be on a linux file system.") % mountpoint)
-
-        if self.rootDevice and self.rootDevice.format.exists:
-            e = self.mustFormat(self.rootDevice)
-            if e:
-                errors.append(e)
-
-        return (errors, warnings)
-
-    def isProtected(self, device):
-        """ Return True is the device is protected. """
-        return device.protected
-
-    def checkNoDisks(self):
-        """Check that there are valid disk devices."""
-        if not self.disks:
-            raise NoDisksError()
-
-    def dumpState(self, suffix):
-        """ Dump the current device list to the storage shelf. """
-        key = "devices.%d.%s" % (time.time(), suffix)
-        with contextlib.closing(shelve.open(self._dumpFile)) as shelf:
-            shelf[key] = [d.dict for d in self.devices]
-
-    @property
-    def packages(self):
-        pkgs = set()
-        pkgs.update(_platform.packages)
-
-        if self.bootloader:
-            pkgs.update(self.bootloader.packages)
-
-        for device in self.fsset.devices:
-            # this takes care of device and filesystem packages
-            pkgs.update(device.packages)
-
-        return list(pkgs)
-
-    def write(self):
-        if not os.path.isdir("%s/etc" % ROOT_PATH):
-            os.mkdir("%s/etc" % ROOT_PATH)
-
-        self.fsset.write()
-        self.makeMtab()
-        self.iscsi.write(self)
-        self.fcoe.write()
-        self.zfcp.write()
-        self.dasd.write()
-
-    def turnOnSwap(self, upgrading=None):
-        self.fsset.turnOnSwap(rootPath=ROOT_PATH,
-                              upgrading=upgrading)
-
-    def mountFilesystems(self, raiseErrors=None, readOnly=None, skipRoot=False):
-        self.fsset.mountFilesystems(rootPath=ROOT_PATH,
-                                    raiseErrors=raiseErrors,
-                                    readOnly=readOnly, skipRoot=skipRoot)
-
-    def umountFilesystems(self, ignoreErrors=True, swapoff=True):
-        self.fsset.umountFilesystems(ignoreErrors=ignoreErrors, swapoff=swapoff)
-
-    def parseFSTab(self, chroot=None):
-        self.fsset.parseFSTab(chroot=chroot)
-
-    def mkDevRoot(self):
-        self.fsset.mkDevRoot()
-
-    def createSwapFile(self, device, size):
-        self.fsset.createSwapFile(device, size)
-
-    @property
-    def bootloader(self):
-        if self._bootloader is None and flags.installer_mode:
-            self._bootloader = get_bootloader()
-
-        return self._bootloader
-
-    def updateBootLoaderDiskList(self):
-        if not self.bootloader:
-            return
-
-        boot_disks = [d for d in self.disks if d.partitioned]
-        boot_disks.sort(cmp=self.compareDisks, key=lambda d: d.name)
-        self.bootloader.set_disk_list(boot_disks)
-
-    def setUpBootLoader(self):
-        """ Propagate ksdata into BootLoader. """
-        if not self.bootloader or not self.data:
-            log.warning("either ksdata or bootloader data missing")
-            return
-
-        if self.bootloader.skip_bootloader:
-            log.info("user specified that bootloader install be skipped")
-            return
-
-        self.bootloader.stage1_disk = self.devicetree.resolveDevice(self.data.bootloader.bootDrive)
-        self.bootloader.stage2_device = self.bootDevice
-        try:
-            self.bootloader.set_stage1_device(self.devices)
-        except BootLoaderError as e:
-            log.debug("failed to set bootloader stage1 device: %s" % e)
-
-    @property
-    def bootDisk(self):
-        disk = None
-        if self.data:
-            spec = self.data.bootloader.bootDrive
-            disk = self.devicetree.resolveDevice(spec)
-        return disk
-
-    @property
-    def bootDevice(self):
-        dev = None
-        if self.fsset:
-            dev = self.mountpoints.get("/boot", self.rootDevice)
-        return dev
-
-    @property
-    def bootLoaderDevice(self):
-        return getattr(self.bootloader, "stage1_device", None)
-
-    @property
-    def bootFSTypes(self):
-        """A list of all valid filesystem types for the boot partition."""
-        fstypes = []
-        if self.bootloader:
-            fstypes = self.bootloader.stage2_format_types
-        return fstypes
-
-    @property
-    def defaultBootFSType(self):
-        """The default filesystem type for the boot partition."""
-        fstype = None
-        if self.bootloader:
-            fstype = self.bootFSTypes[0]
-        return fstype
-
-    @property
-    def mountpoints(self):
-        return self.fsset.mountpoints
-
-    @property
-    def rootDevice(self):
-        return self.fsset.rootDevice
-
-    def makeMtab(self):
-        path = "/etc/mtab"
-        target = "/proc/self/mounts"
-        path = os.path.normpath("%s/%s" % (ROOT_PATH, path))
-
-        if os.path.islink(path):
-            # return early if the mtab symlink is already how we like it
-            current_target = os.path.normpath(os.path.dirname(path) +
-                                              "/" + os.readlink(path))
-            if current_target == target:
-                return
-
-        if os.path.exists(path):
-            os.unlink(path)
-
-        os.symlink(target, path)
-
-    def compareDisks(self, first, second):
-        if self.eddDict.has_key(first) and self.eddDict.has_key(second):
-            one = self.eddDict[first]
-            two = self.eddDict[second]
-            if (one < two):
-                return -1
-            elif (one > two):
-                return 1
-
-        # if one is in the BIOS and the other not prefer the one in the BIOS
-        if self.eddDict.has_key(first):
-            return -1
-        if self.eddDict.has_key(second):
-            return 1
-
-        if first.startswith("hd"):
-            type1 = 0
-        elif first.startswith("sd"):
-            type1 = 1
-        elif (first.startswith("vd") or first.startswith("xvd")):
-            type1 = -1
-        else:
-            type1 = 2
-
-        if second.startswith("hd"):
-            type2 = 0
-        elif second.startswith("sd"):
-            type2 = 1
-        elif (second.startswith("vd") or second.startswith("xvd")):
-            type2 = -1
-        else:
-            type2 = 2
-
-        if (type1 < type2):
-            return -1
-        elif (type1 > type2):
-            return 1
-        else:
-            len1 = len(first)
-            len2 = len(second)
-
-            if (len1 < len2):
-                return -1
-            elif (len1 > len2):
-                return 1
-            else:
-                if (first < second):
-                    return -1
-                elif (first > second):
-                    return 1
-
-        return 0
-
-    def getFSType(self, mountpoint=None):
-        """ Return the default filesystem type based on mountpoint. """
-        fstype = self.defaultFSType
-        if not mountpoint:
-            # just return the default
-            pass
-        elif mountpoint.lower() in ("swap", "biosboot", "prepboot"):
-            fstype = mountpoint.lower()
-        elif mountpoint == "/boot":
-            fstype = self.defaultBootFSType
-        elif mountpoint == "/boot/efi":
-            if arch.isMactel():
-                fstype = "hfs+"
-            else:
-                fstype = "efi"
-
-        return fstype
-
-    def setContainerMembers(self, container, factory, members=None,
-                            device=None):
-        """ Set up and return the container's member partitions. """
-        log_members = []
-        if members:
-            log_members = [str(m) for m in members]
-        log_method_call(self, container=container, factory=factory,
-                        members=log_members, device=device)
-        if factory.member_list is not None:
-            # short-circuit the logic below for partitions
-            return factory.member_list
-
-        if container and container.exists:
-            # don't try to modify an existing container
-            return container.parents
-
-        if factory.container_size_func is None:
-            return []
-
-        # set up member devices
-        container_size = factory.device_size
-        add_disks = []
-        remove_disks = []
-
-        if members is None:
-            members = []
-
-        if container:
-            members = container.parents[:]
-        elif members:
-            # mdarray
-            container = device
-
-        # The basis for whether we are modifying a member set versus creating
-        # one must be the member list, as container will be None when modifying
-        # the member set of an md array.
-
-        # XXX how can we detect/handle failure to use one or more of the disks?
-        if members and device:
-            # See if we need to add/remove any disks, but only if we are
-            # adjusting a device. When adding a new device to a container we do
-            # not want to modify the container's disk set.
-            _disks = list(set([d for m in members for d in m.disks]))
-
-            add_disks = [d for d in factory.disks if d not in _disks]
-            remove_disks = [d for d in _disks if d not in factory.disks]
-        elif not members:
-            # new container, so use the factory's disk set
-            add_disks = factory.disks
-
-        # drop any new disks that don't have free space
-        min_free = min(500, factory.size)
-        add_disks = [d for d in add_disks if d.partitioned and
-                                             d.format.free >= min_free]
-
-        base_size = max(1, getFormat(factory.member_format).minSize)
-
-        # XXX TODO: multiple member devices per disk
-
-        # prepare already-defined member partitions for reallocation
-        for member in members[:]:
-            if any([d in remove_disks for d in member.disks]):
-                if isinstance(member, LUKSDevice):
-                    if container:
-                        container.removeMember(member)
-                    self.destroyDevice(member)
-                    members.remove(member)
-                    member = member.slave
-                else:
-                    if container:
-                        container.removeMember(member)
-
-                    members.remove(member)
-
-                self.destroyDevice(member)
-                continue
-
-            if isinstance(member, LUKSDevice):
-                if not factory.encrypted:
-                    # encryption was toggled for the member devices
-                    if container:
-                        container.removeMember(member)
-
-                    self.destroyDevice(member)
-                    members.remove(member)
-
-                    self.formatDevice(member.slave,
-                                      getFormat(factory.member_format))
-                    members.append(member.slave)
-                    if container:
-                        container.addMember(member.slave)
-
-                member = member.slave
-            elif factory.encrypted:
-                # encryption was toggled for the member devices
-                if container:
-                    container.removeMember(member)
-
-                members.remove(member)
-                self.formatDevice(member, getFormat("luks"))
-                luks_member = LUKSDevice("luks-%s" % member.name,
-                                    parents=[member],
-                                    format=getFormat(factory.member_format))
-                self.createDevice(luks_member)
-                members.append(luks_member)
-                if container:
-                    container.addMember(luks_member)
-
-            member.req_base_size = base_size
-            member.req_size = member.req_base_size
-            member.req_grow = True
-
-        # set up new members as needed to accommodate the device
-        new_members = []
-        for disk in add_disks:
-            if factory.encrypted and factory.encrypt_members:
-                luks_format = factory.member_format
-                member_format = "luks"
-            else:
-                member_format = factory.member_format
-
-            try:
-                member = self.newPartition(parents=[disk], grow=True,
-                                           size=base_size,
-                                           fmt_type=member_format)
-            except StorageError as e:
-                log.error("failed to create new member partition: %s" % e)
-                continue
-
-            self.createDevice(member)
-            if factory.encrypted and factory.encrypt_members:
-                fmt = getFormat(luks_format)
-                member = LUKSDevice("luks-%s" % member.name,
-                                    parents=[member], format=fmt)
-                self.createDevice(member)
-
-            members.append(member)
-            new_members.append(member)
-            if container:
-                container.addMember(member)
-
-        if container:
-            log.debug("using container %s with %d devices" % (container.name,
-                                len(self.devicetree.getChildren(container))))
-            container_size = factory.container_size_func(container, device)
-            log.debug("raw container size reported as %d" % container_size)
-
-        log.debug("adding a %s with size %d" % (factory.set_class.__name__,
-                                                container_size))
-        size_set = factory.set_class(members, container_size)
-        self.size_sets.append(size_set)
-        for member in members[:]:
-            if isinstance(member, LUKSDevice):
-                member = member.slave
-
-            member.req_max_size = size_set.size
-
-        try:
-            self.allocatePartitions()
-        except PartitioningError as e:
-            # try to clean up by destroying all newly added members before re-
-            # raising the exception
-            self.__cleanUpMemberDevices(new_members, container=container)
-            raise
-
-        return members
-
-    def allocatePartitions(self):
-        """ Allocate all requested partitions. """
-        try:
-            doPartitioning(self)
-        except StorageError as e:
-            log.error("failed to allocate partitions: %s" % e)
-            raise
-
-    def getDeviceFactory(self, device_type, size, **kwargs):
-        """ Return a suitable DeviceFactory instance for device_type. """
-        disks = kwargs.get("disks", [])
-        raid_level = kwargs.get("raid_level")
-        encrypted = kwargs.get("encrypted", False)
-
-        class_table = {DEVICE_TYPE_LVM: LVMFactory,
-                       DEVICE_TYPE_BTRFS: BTRFSFactory,
-                       DEVICE_TYPE_PARTITION: PartitionFactory,
-                       DEVICE_TYPE_MD: MDFactory,
-                       DEVICE_TYPE_DISK: DiskFactory}
-
-        factory_class = class_table[device_type]
-        log.debug("instantiating %s: %r, %s, %s, %s" % (factory_class,
-                    self, size, [d.name for d in disks], raid_level))
-        return factory_class(self, size, disks, raid_level, encrypted)
-
-    def getContainer(self, factory, device=None, name=None, existing=False):
-        # XXX would it be useful to implement this as a series of fallbacks
-        #     instead of mutually exclusive branches?
-        container = None
-        if name:
-            container = self.devicetree.getDeviceByName(name)
-            if container and container not in factory.container_list:
-                log.debug("specified container name %s is wrong type (%s)"
-                            % (name, container.type))
-                container = None
-        elif device:
-            if hasattr(device, "vg"):
-                container = device.vg
-            elif hasattr(device, "volume"):
-                container = device.volume
-        else:
-            containers = [c for c in factory.container_list if not c.exists]
-            if containers:
-                container = containers[0]
-
-        if container is None and existing:
-            containers = [c for c in factory.container_list if c.exists]
-            if containers:
-                containers.sort(key=lambda c: getattr(c, "freeSpace", c.size),
-                                reverse=True)
-                container = containers[0]
-
-        return container
-
-    def __cleanUpMemberDevices(self, members, container=None):
-        for member in members:
-            if container:
-                container.removeMember(member)
-
-            if isinstance(member, LUKSDevice):
-                self.destroyDevice(member)
-                member = member.slave
-
-            if not member.isDisk:
-                self.destroyDevice(member)
-
-    def newDevice(self, device_type, size, **kwargs):
-        """ Schedule creation of a device based on a top-down specification.
-
-            Arguments:
-
-                device_type         an AUTOPART_TYPE constant (lvm|btrfs|plain)
-                size                device's requested size
-
-            Keyword arguments:
-
-                mountpoint          the device's mountpoint
-                fstype              the device's filesystem type, or swap
-                label               filesystem label
-                disks               the set of disks we can allocate from
-                encrypted           boolean
-
-                raid_level          (btrfs/md/lvm only) RAID level (string)
-
-                name                name for new device
-                container_name      name of requested container
-
-                device              an already-defined but non-existent device
-                                    to adjust instead of creating a new device
-
-
-            Error handling:
-
-                If device is None, meaning we're creating a device, the error
-                handling aims to remove all evidence of the attempt to create a
-                new device by removing unused container devices, reverting the
-                size of container devices that contain other devices, &c.
-
-                If the device is not None, meaning we're adjusting the size of
-                a defined device, the error handling aims to revert the device
-                and any container to it previous size.
-
-                In either case, we re-raise the exception so the caller knows
-                there was a failure. If we failed to clean up as described above
-                we raise ErrorRecoveryFailure to alert the caller that things
-                will likely be in an inconsistent state.
-        """
-        log_method_call(self, device_type, size, **kwargs)
-        mountpoint = kwargs.get("mountpoint")
-        fstype = kwargs.get("fstype")
-        label = kwargs.get("label")
-        disks = kwargs.get("disks")
-        encrypted = kwargs.get("encrypted", self.data.autopart.encrypted)
-
-        name = kwargs.get("name")
-        container_name = kwargs.get("container_name")
-
-        device = kwargs.get("device")
-
-        # md, btrfs
-        raid_level = kwargs.get("raid_level")
-
-        # we can't do anything with existing devices
-        if device and device.exists:
-            log.info("newDevice refusing to change device %s" % device)
-            return
-
-        if not fstype:
-            fstype = self.getFSType(mountpoint=mountpoint)
-            if fstype == "swap":
-                mountpoint = None
-
-        if fstype == "swap" and device_type == DEVICE_TYPE_BTRFS:
-            device_type = DEVICE_TYPE_PARTITION
-
-        fmt_args = {}
-        if label:
-            fmt_args["label"] = label
-
-        factory = self.getDeviceFactory(device_type, size, **kwargs)
-
-        if not factory.disks:
-            raise StorageError("no disks specified for new device")
-
-        self.size_sets = [] # clear this since there are no growable reqs now
-
-        container = self.getContainer(factory, device=device,
-                                      name=container_name)
-
-        # TODO: striping, mirroring, &c
-        # TODO: non-partition members (pv-on-md)
-
-        # setContainerMembers can modify these, so save them now
-        old_size = None
-        old_disks = []
-        if device:
-            old_size = device.size
-            old_disks = device.disks[:]
-
-        members = []
-        if device and device.type == "mdarray":
-            members = device.parents[:]
-
-        try:
-            parents = self.setContainerMembers(container, factory,
-                                               members=members, device=device)
-        except PartitioningError as e:
-            # If this is a new device, just clean up and get out.
-            if device:
-                # If this is a defined device, try to clean up by reallocating
-                # members as before and then get out.
-                factory.disks = device.disks
-                factory.size = device.size  # this should work
-
-                if members:
-                    # If this is an md array we have to reset its member set
-                    # here.
-                    # If there is a container device, its member set was reset
-                    # in the exception handler in setContainerMembers.
-                    device.parents = members
-
-                try:
-                    self.setContainerMembers(container, factory,
-                                             members=members,
-                                             device=device)
-                except StorageError as e:
-                    log.error("failed to revert device size: %s" % e)
-                    raise ErrorRecoveryFailure("failed to revert container")
-
-            raise
-
-        # set up container
-        if not container and factory.new_container_attr:
-            if not parents:
-                raise StorageError("not enough free space on disks")
-
-            log.debug("creating new container")
-            if container_name:
-                kwa = {"name": container_name}
-            else:
-                kwa = {}
-            try:
-                container = factory.new_container(parents=parents, **kwa)
-            except StorageError as e:
-                log.error("failed to create new device: %s" % e)
-                # Clean up by destroying the newly created member devices.
-                self.__cleanUpMemberDevices(parents)
-                raise
-
-            self.createDevice(container)
-        elif container and not container.exists and \
-             hasattr(container, "dataLevel"):
-            container.dataLevel = factory.raid_level
-
-        if container:
-            parents = [container]
-            log.debug("%r" % container)
-
-        # this will set the device's size if a device is passed in
-        size = factory.set_device_size(container, device=device)
-        if device:
-            # We are adjusting a defined device: size, disk set, encryption,
-            # raid level, fstype. The StorageDevice instance exists, but the
-            # underlying device does not.
-            # TODO: handle toggling of encryption for leaf device
-            e = None
-            try:
-                factory.post_create()
-            except StorageError as e:
-                log.error("device post-create method failed: %s" % e)
-            else:
-                if device.size <= device.format.minSize:
-                    e = StorageError("failed to adjust device -- not enough free space in specified disks?")
-
-            if e:
-                # Clean up by reverting the device to its previous size.
-                factory.size = old_size
-                factory.disks = old_disks
-                try:
-                    self.setContainerMembers(container, factory,
-                                             members=members, device=device)
-                except StorageError as e:
-                    # yes, we're replacing e here.
-                    log.error("failed to revert device size: %s" % e)
-                    raise ErrorRecoveryFailure("failed to revert device size")
-
-                factory.set_device_size(container, device=device)
-                try:
-                    factory.post_create()
-                except StorageError as e:
-                    # yes, we're replacing e here.
-                    log.error("failed to revert device size: %s" % e)
-                    raise ErrorRecoveryFailure("failed to revert device size")
-
-                raise(e)
-        elif factory.new_device_attr:
-            log.debug("creating new device")
-            if factory.encrypted and factory.encrypt_leaves:
-                luks_fmt_type = fstype
-                luks_fmt_args = fmt_args
-                luks_mountpoint = mountpoint
-                fstype = "luks"
-                mountpoint = None
-                fmt_args = {}
-
-            def _container_post_error():
-                # Clean up. If there is a container and it has other devices,
-                # try to revert it. If there is a container and it has no other
-                # devices, remove it. If there is not a container, remove all of
-                # the parents.
-                if container:
-                    if container.kids:
-                        factory.size = 0
-                        factory.disks = container.disks
-                        try:
-                            self.setContainerMembers(container, factory)
-                        except StorageError as e:
-                            log.error("failed to revert container: %s" % e)
-                            raise ErrorRecoveryFailure("failed to revert container")
-                    else:
-                        self.destroyDevice(container)
-                        self.__cleanUpMemberDevices(container.parents)
-                else:
-                    self.__cleanUpMemberDevices(parents)
-
-            if name:
-                kwa = {"name": name}
-            else:
-                kwa = {}
-
-            try:
-                device = factory.new_device(parents=parents,
-                                            size=size,
-                                            fmt_type=fstype,
-                                            mountpoint=mountpoint,
-                                            fmt_args=fmt_args,
-                                            **kwa)
-            except (StorageError, ValueError) as e:
-                log.error("device instance creation failed: %s" % e)
-                _container_post_error()
-                raise
-
-            self.createDevice(device)
-            e = None
-            try:
-                factory.post_create()
-            except StorageError as e:
-                log.error("device post-create method failed: %s" % e)
-            else:
-                if not device.size:
-                    e = StorageError("failed to create device")
-
-            if e:
-                self.destroyDevice(device)
-                _container_post_error()
-                raise StorageError(e)
-
-            if factory.encrypted and factory.encrypt_leaves:
-                fmt = getFormat(luks_fmt_type,
-                                mountpoint=luks_mountpoint,
-                                **luks_fmt_args)
-                luks_device = LUKSDevice("luks-" + device.name,
-                                         parents=[device], format=fmt)
-                self.createDevice(luks_device)
-
-    def copy(self):
-        new = copy.deepcopy(self)
-        # go through and re-get partedPartitions from the disks since they
-        # don't get deep-copied
-        for partition in new.partitions:
-            if not partition._partedPartition:
-                continue
-
-            # don't ask me why, but we have to update the refs in req_disks
-            req_disks = []
-            for disk in partition.req_disks:
-                req_disks.append(new.devicetree.getDeviceByID(disk.id))
-
-            partition.req_disks = req_disks
-
-            p = partition.disk.format.partedDisk.getPartitionByPath(partition.path)
-            partition.partedPartition = p
-
-        return new
-
-
-def mountExistingSystem(fsset, rootDevice,
-                        allowDirty=None, dirtyCB=None,
-                        readOnly=None):
-    """ Mount filesystems specified in rootDevice's /etc/fstab file. """
-    rootPath = ROOT_PATH
-    if dirtyCB is None:
-        dirtyCB = lambda l: False
-
-    if readOnly:
-        readOnly = "ro"
-    else:
-        readOnly = ""
-
-    if rootDevice.protected and os.path.ismount("/mnt/install/isodir"):
-        util.mount("/mnt/install/isodir",
-                   rootPath,
-                   fstype=rootDevice.format.type,
-                   options="bind")
-    else:
-        rootDevice.setup()
-        rootDevice.format.mount(chroot=rootPath,
-                                mountpoint="/",
-                                options=readOnly)
-
-    fsset.parseFSTab()
-
-    # check for dirty filesystems
-    dirtyDevs = []
-    for device in fsset.mountpoints.values():
-        if not hasattr(device.format, "needsFSCheck"):
-            continue
-
-        try:
-            device.setup()
-        except DeviceError as e:
-            # we'll catch this in the main loop
-            continue
-
-        if device.format.needsFSCheck:
-            log.info("%s contains a dirty %s filesystem" % (device.path,
-                                                            device.format.type))
-            dirtyDevs.append(device.path)
-
-    if dirtyDevs and (not allowDirty or dirtyCB(dirtyDevs)):
-        raise DirtyFSError("\n".join(dirtyDevs))
-
-    fsset.mountFilesystems(rootPath=ROOT_PATH, readOnly=readOnly, skipRoot=True)
-
-
-class BlkidTab(object):
-    """ Dictionary-like interface to blkid.tab with device path keys """
-    def __init__(self, chroot=""):
-        self.chroot = chroot
-        self.devices = {}
-
-    def parse(self):
-        path = "%s/etc/blkid/blkid.tab" % self.chroot
-        log.debug("parsing %s" % path)
-        with open(path) as f:
-            for line in f.readlines():
-                # this is pretty ugly, but an XML parser is more work than
-                # is justifiable for this purpose
-                if not line.startswith("<device "):
-                    continue
-
-                line = line[len("<device "):-len("</device>\n")]
-                (data, sep, device) = line.partition(">")
-                if not device:
-                    continue
-
-                self.devices[device] = {}
-                for pair in data.split():
-                    try:
-                        (key, value) = pair.split("=")
-                    except ValueError:
-                        continue
-
-                    self.devices[device][key] = value[1:-1] # strip off quotes
-
-    def __getitem__(self, key):
-        return self.devices[key]
-
-    def get(self, key, default=None):
-        return self.devices.get(key, default)
-
-
-class CryptTab(object):
-    """ Dictionary-like interface to crypttab entries with map name keys """
-    def __init__(self, devicetree, blkidTab=None, chroot=""):
-        self.devicetree = devicetree
-        self.blkidTab = blkidTab
-        self.chroot = chroot
-        self.mappings = {}
-
-    def parse(self, chroot=""):
-        """ Parse /etc/crypttab from an existing installation. """
-        if not chroot or not os.path.isdir(chroot):
-            chroot = ""
-
-        path = "%s/etc/crypttab" % chroot
-        log.debug("parsing %s" % path)
-        with open(path) as f:
-            if not self.blkidTab:
-                try:
-                    self.blkidTab = BlkidTab(chroot=chroot)
-                    self.blkidTab.parse()
-                except Exception:
-                    self.blkidTab = None
-
-            for line in f.readlines():
-                (line, pound, comment) = line.partition("#")
-                fields = line.split()
-                if not 2 <= len(fields) <= 4:
-                    continue
-                elif len(fields) == 2:
-                    fields.extend(['none', ''])
-                elif len(fields) == 3:
-                    fields.append('')
-
-                (name, devspec, keyfile, options) = fields
-
-                # resolve devspec to a device in the tree
-                device = self.devicetree.resolveDevice(devspec,
-                                                       blkidTab=self.blkidTab)
-                if device:
-                    self.mappings[name] = {"device": device,
-                                           "keyfile": keyfile,
-                                           "options": options}
-
-    def populate(self):
-        """ Populate the instance based on the device tree's contents. """
-        for device in self.devicetree.devices:
-            # XXX should we put them all in there or just the ones that
-            #     are part of a device containing swap or a filesystem?
-            #
-            #       Put them all in here -- we can filter from FSSet
-            if device.format.type != "luks":
-                continue
-
-            key_file = device.format.keyFile
-            if not key_file:
-                key_file = "none"
-
-            options = device.format.options
-            if not options:
-                options = ""
-
-            self.mappings[device.format.mapName] = {"device": device,
-                                                    "keyfile": key_file,
-                                                    "options": options}
-
-    def crypttab(self):
-        """ Write out /etc/crypttab """
-        crypttab = ""
-        for name in self.mappings:
-            entry = self[name]
-            crypttab += "%s UUID=%s %s %s\n" % (name,
-                                                entry['device'].format.uuid,
-                                                entry['keyfile'],
-                                                entry['options'])
-        return crypttab                       
-
-    def __getitem__(self, key):
-        return self.mappings[key]
-
-    def get(self, key, default=None):
-        return self.mappings.get(key, default)
-
-def get_containing_device(path, devicetree):
-    """ Return the device that a path resides on. """
-    if not os.path.exists(path):
-        return None
-
-    st = os.stat(path)
-    major = os.major(st.st_dev)
-    minor = os.minor(st.st_dev)
-    link = "/sys/dev/block/%s:%s" % (major, minor)
-    if not os.path.exists(link):
-        return None
-
-    try:
-        device_name = os.path.basename(os.readlink(link))
-    except Exception:
-        return None
-
-    if device_name.startswith("dm-"):
-        # have I told you lately that I love you, device-mapper?
-        device_name = name_from_dm_node(device_name)
-
-    return devicetree.getDeviceByName(device_name)
-
-
-class FSSet(object):
-    """ A class to represent a set of filesystems. """
-    def __init__(self, devicetree):
-        self.devicetree = devicetree
-        self.cryptTab = None
-        self.blkidTab = None
-        self.origFStab = None
-        self.active = False
-        self._dev = None
-        self._devpts = None
-        self._sysfs = None
-        self._proc = None
-        self._devshm = None
-        self._usb = None
-        self._selinux = None
-        self.preserveLines = []     # lines we just ignore and preserve
-
-    @property
-    def sysfs(self):
-        if not self._sysfs:
-            self._sysfs = NoDevice(format=getFormat("sysfs",
-                                                    device="sys",
-                                                    mountpoint="/sys"))
-        return self._sysfs
-
-    @property
-    def dev(self):
-        if not self._dev:
-            self._dev = DirectoryDevice("/dev", format=getFormat("bind",
-                                                                 device="/dev",
-                                                                 mountpoint="/dev",
-                                                                 exists=True),
-                                        exists=True)
-
-        return self._dev
-
-    @property
-    def devpts(self):
-        if not self._devpts:
-            self._devpts = NoDevice(format=getFormat("devpts",
-                                                     device="devpts",
-                                                     mountpoint="/dev/pts"))
-        return self._devpts
-
-    @property
-    def proc(self):
-        if not self._proc:
-            self._proc = NoDevice(format=getFormat("proc",
-                                                   device="proc",
-                                                   mountpoint="/proc"))
-        return self._proc
-
-    @property
-    def devshm(self):
-        if not self._devshm:
-            self._devshm = NoDevice(format=getFormat("tmpfs",
-                                                     device="tmpfs",
-                                                     mountpoint="/dev/shm"))
-        return self._devshm
-
-    @property
-    def usb(self):
-        if not self._usb:
-            self._usb = NoDevice(format=getFormat("usbfs",
-                                                  device="usbfs",
-                                                  mountpoint="/proc/bus/usb"))
-        return self._usb
-
-    @property
-    def selinux(self):
-        if not self._selinux:
-            self._selinux = NoDevice(format=getFormat("selinuxfs",
-                                                      device="selinuxfs",
-                                                      mountpoint="/sys/fs/selinux"))
-        return self._selinux
-
-    @property
-    def devices(self):
-        return sorted(self.devicetree.devices, key=lambda d: d.path)
-
-    @property
-    def mountpoints(self):
-        filesystems = {}
-        for device in self.devices:
-            if device.format.mountable and device.format.mountpoint:
-                filesystems[device.format.mountpoint] = device
-        return filesystems
-
-    def _parseOneLine(self, (devspec, mountpoint, fstype, options, dump, passno)):
-        # no sense in doing any legwork for a noauto entry
-        if "noauto" in options.split(","):
-            log.info("ignoring noauto entry")
-            raise UnrecognizedFSTabEntryError()
-
-        # find device in the tree
-        device = self.devicetree.resolveDevice(devspec,
-                                               cryptTab=self.cryptTab,
-                                               blkidTab=self.blkidTab)
-
-        if device:
-            # fall through to the bottom of this block
-            pass
-        elif devspec.startswith("/dev/loop"):
-            # FIXME: create devices.LoopDevice
-            log.warning("completely ignoring your loop mount")
-        elif ":" in devspec and fstype.startswith("nfs"):
-            # NFS -- preserve but otherwise ignore
-            device = NFSDevice(devspec,
-                               exists=True,
-                               format=getFormat(fstype,
-                                                exists=True,
-                                                device=devspec))
-        elif devspec.startswith("/") and fstype == "swap":
-            # swap file
-            device = FileDevice(devspec,
-                                parents=get_containing_device(devspec, self.devicetree),
-                                format=getFormat(fstype,
-                                                 device=devspec,
-                                                 exists=True),
-                                exists=True)
-        elif fstype == "bind" or "bind" in options:
-            # bind mount... set fstype so later comparison won't
-            # turn up false positives
-            fstype = "bind"
-
-            # This is probably not going to do anything useful, so we'll
-            # make sure to try again from FSSet.mountFilesystems. The bind
-            # mount targets should be accessible by the time we try to do
-            # the bind mount from there.
-            parents = get_containing_device(devspec, self.devicetree)
-            device = DirectoryDevice(devspec, parents=parents, exists=True)
-            device.format = getFormat("bind",
-                                      device=device.path,
-                                      exists=True)
-        elif mountpoint in ("/proc", "/sys", "/dev/shm", "/dev/pts",
-                            "/sys/fs/selinux", "/proc/bus/usb"):
-            # drop these now -- we'll recreate later
-            return None
-        else:
-            # nodev filesystem -- preserve or drop completely?
-            format = getFormat(fstype)
-            if devspec == "none" or \
-               isinstance(format, get_device_format_class("nodev")):
-                device = NoDevice(format=format)
-
-        if device is None:
-            log.error("failed to resolve %s (%s) from fstab" % (devspec,
-                                                                fstype))
-            raise UnrecognizedFSTabEntryError()
-
-        device.setup()
-        fmt = getFormat(fstype, device=device.path, exists=True)
-        if fstype != "auto" and None in (device.format.type, fmt.type):
-            log.info("Unrecognized filesystem type for %s (%s)"
-                     % (device.name, fstype))
-            device.teardown()
-            raise UnrecognizedFSTabEntryError()
-
-        # make sure, if we're using a device from the tree, that
-        # the device's format we found matches what's in the fstab
-        ftype = getattr(fmt, "mountType", fmt.type)
-        dtype = getattr(device.format, "mountType", device.format.type)
-        if fstype != "auto" and ftype != dtype:
-            log.info("fstab says %s at %s is %s" % (dtype, mountpoint, ftype))
-            if fmt.testMount():
-                device.format = fmt
-            else:
-                device.teardown()
-                raise FSTabTypeMismatchError("%s: detected as %s, fstab says %s"
-                                             % (mountpoint, dtype, ftype))
-        del ftype
-        del dtype
-
-        if device.format.mountable:
-            device.format.mountpoint = mountpoint
-            device.format.mountopts = options
-
-        # is this useful?
-        try:
-            device.format.options = options
-        except AttributeError:
-            pass
-
-        return device
-
-    def parseFSTab(self, chroot=None):
-        """ parse /etc/fstab
-
-            preconditions:
-                all storage devices have been scanned, including filesystems
-            postconditions:
-
-            FIXME: control which exceptions we raise
-
-            XXX do we care about bind mounts?
-                how about nodev mounts?
-                loop mounts?
-        """
-        if not chroot or not os.path.isdir(chroot):
-            chroot = ROOT_PATH
-
-        path = "%s/etc/fstab" % chroot
-        if not os.access(path, os.R_OK):
-            # XXX should we raise an exception instead?
-            log.info("cannot open %s for read" % path)
-            return
-
-        blkidTab = BlkidTab(chroot=chroot)
-        try:
-            blkidTab.parse()
-            log.debug("blkid.tab devs: %s" % blkidTab.devices.keys())
-        except Exception as e:
-            log.info("error parsing blkid.tab: %s" % e)
-            blkidTab = None
-
-        cryptTab = CryptTab(self.devicetree, blkidTab=blkidTab, chroot=chroot)
-        try:
-            cryptTab.parse(chroot=chroot)
-            log.debug("crypttab maps: %s" % cryptTab.mappings.keys())
-        except Exception as e:
-            log.info("error parsing crypttab: %s" % e)
-            cryptTab = None
-
-        self.blkidTab = blkidTab
-        self.cryptTab = cryptTab
-
-        with open(path) as f:
-            log.debug("parsing %s" % path)
-
-            lines = f.readlines()
-
-            # save the original file
-            self.origFStab = ''.join(lines)
-
-            for line in lines:
-                # strip off comments
-                (line, pound, comment) = line.partition("#")
-                fields = line.split()
-
-                if not 4 <= len(fields) <= 6:
-                    continue
-                elif len(fields) == 4:
-                    fields.extend([0, 0])
-                elif len(fields) == 5:
-                    fields.append(0)
-
-                (devspec, mountpoint, fstype, options, dump, passno) = fields
-
-                try:
-                    device = self._parseOneLine((devspec, mountpoint, fstype, options, dump, passno))
-                except UnrecognizedFSTabEntryError:
-                    # just write the line back out as-is after upgrade
-                    self.preserveLines.append(line)
-                    continue
-
-                if not device:
-                    continue
-
-                if device not in self.devicetree.devices:
-                    try:
-                        self.devicetree._addDevice(device)
-                    except ValueError:
-                        # just write duplicates back out post-install
-                        self.preserveLines.append(line)
-
-    def turnOnSwap(self, rootPath="", upgrading=None):
-        """ Activate the system's swap space. """
-        if not flags.installer_mode:
-            return
-
-        for device in self.swapDevices:
-            if isinstance(device, FileDevice):
-                # set up FileDevices' parents now that they are accessible
-                targetDir = "%s/%s" % (rootPath, device.path)
-                parent = get_containing_device(targetDir, self.devicetree)
-                if not parent:
-                    log.error("cannot determine which device contains "
-                              "directory %s" % device.path)
-                    device.parents = []
-                    self.devicetree._removeDevice(device)
-                    continue
-                else:
-                    device.parents = [parent]
-
-            while True:
-                try:
-                    device.setup()
-                    device.format.setup()
-                except StorageError as e:
-                    if errorHandler.cb(e, device) == ERROR_RAISE:
-                        raise
-                else:
-                    break
-
-    def mountFilesystems(self, rootPath="", readOnly=None,
-                         skipRoot=False, raiseErrors=None):
-        """ Mount the system's filesystems. """
-        if not flags.installer_mode:
-            return
-
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs,
-                        self.proc, self.selinux, self.usb])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-
-        for device in devices:
-            if not device.format.mountable or not device.format.mountpoint:
-                continue
-
-            if skipRoot and device.format.mountpoint == "/":
-                continue
-
-            options = device.format.options
-            if "noauto" in options.split(","):
-                continue
-
-            if device.format.type == "bind" and device != self.dev:
-                # set up the DirectoryDevice's parents now that they are
-                # accessible
-                #
-                # -- bind formats' device and mountpoint are always both
-                #    under the chroot. no exceptions. none, damn it.
-                targetDir = "%s/%s" % (rootPath, device.path)
-                parent = get_containing_device(targetDir, self.devicetree)
-                if not parent:
-                    log.error("cannot determine which device contains "
-                              "directory %s" % device.path)
-                    device.parents = []
-                    self.devicetree._removeDevice(device)
-                    continue
-                else:
-                    device.parents = [parent]
-
-            try:
-                device.setup()
-            except Exception as e:
-                if errorHandler.cb(e, device) == ERROR_RAISE:
-                    raise
-                else:
-                    continue
-
-            if readOnly:
-                options = "%s,%s" % (options, readOnly)
-
-            try:
-                device.format.setup(options=options,
-                                    chroot=rootPath)
-            except Exception as e:
-                log.error("error mounting %s on %s: %s"
-                          % (device.path, device.format.mountpoint, e))
-                if errorHandler.cb(e, device) == ERROR_RAISE:
-                    raise
-
-        self.active = True
-
-    def umountFilesystems(self, ignoreErrors=True, swapoff=True):
-        """ unmount filesystems, except swap if swapoff == False """
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs,
-                        self.proc, self.usb, self.selinux])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-        devices.reverse()
-        for device in devices:
-            if (not device.format.mountable) or \
-               (device.format.type == "swap" and not swapoff):
-                continue
-
-            device.format.teardown()
-            device.teardown()
-
-        self.active = False
-
-    def createSwapFile(self, device, size):
-        """ Create and activate a swap file under ROOT_PATH. """
-        filename = "/SWAP"
-        count = 0
-        basedir = os.path.normpath("%s/%s" % (ROOT_PATH,
-                                              device.format.mountpoint))
-        while os.path.exists("%s/%s" % (basedir, filename)) or \
-              self.devicetree.getDeviceByName(filename):
-            file = os.path.normpath("%s/%s" % (basedir, filename))
-            count += 1
-            filename = "/SWAP-%d" % count
-
-        dev = FileDevice(filename,
-                         size=size,
-                         parents=[device],
-                         format=getFormat("swap", device=filename))
-        dev.create()
-        dev.setup()
-        dev.format.create()
-        dev.format.setup()
-        # nasty, nasty
-        self.devicetree._addDevice(dev)
-
-    def mkDevRoot(self):
-        root = self.rootDevice
-        dev = "%s/%s" % (ROOT_PATH, root.path)
-        if not os.path.exists("%s/dev/root" %(ROOT_PATH,)) and os.path.exists(dev):
-            rdev = os.stat(dev).st_rdev
-            os.mknod("%s/dev/root" % (ROOT_PATH,), stat.S_IFBLK | 0600, rdev)
-
-    @property
-    def swapDevices(self):
-        swaps = []
-        for device in self.devices:
-            if device.format.type == "swap":
-                swaps.append(device)
-        return swaps
-
-    @property
-    def rootDevice(self):
-        for path in ["/", ROOT_PATH]:
-            for device in self.devices:
-                try:
-                    mountpoint = device.format.mountpoint
-                except AttributeError:
-                    mountpoint = None
-
-                if mountpoint == path:
-                    return device
-
-    def write(self):
-        """ write out all config files based on the set of filesystems """
-        # /etc/fstab
-        fstab_path = os.path.normpath("%s/etc/fstab" % ROOT_PATH)
-        fstab = self.fstab()
-        open(fstab_path, "w").write(fstab)
-
-        # /etc/crypttab
-        crypttab_path = os.path.normpath("%s/etc/crypttab" % ROOT_PATH)
-        crypttab = self.crypttab()
-        origmask = os.umask(0077)
-        open(crypttab_path, "w").write(crypttab)
-        os.umask(origmask)
-
-        # /etc/mdadm.conf
-        mdadm_path = os.path.normpath("%s/etc/mdadm.conf" % ROOT_PATH)
-        mdadm_conf = self.mdadmConf()
-        if mdadm_conf:
-            open(mdadm_path, "w").write(mdadm_conf)
-
-        # /etc/multipath.conf
-        multipath_conf = self.multipathConf()
-        if multipath_conf:
-            multipath_path = os.path.normpath("%s/etc/multipath.conf" %
-                                              ROOT_PATH)
-            conf_contents = multipath_conf.write(self.devicetree.mpathFriendlyNames)
-            f = open(multipath_path, "w")
-            f.write(conf_contents)
-            f.close()
-        else:
-            log.info("not writing out mpath configuration")
-        util.copy_to_system("/etc/multipath/wwids")
-        if self.devicetree.mpathFriendlyNames:
-            util.copy_to_system("/etc/multipath/bindings")
-
-    def crypttab(self):
-        # if we are upgrading, do we want to update crypttab?
-        # gut reaction says no, but plymouth needs the names to be very
-        # specific for passphrase prompting
-        if not self.cryptTab:
-            self.cryptTab = CryptTab(self.devicetree)
-            self.cryptTab.populate()
-
-        devices = self.mountpoints.values() + self.swapDevices
-
-        # prune crypttab -- only mappings required by one or more entries
-        for name in self.cryptTab.mappings.keys():
-            keep = False
-            mapInfo = self.cryptTab[name]
-            cryptoDev = mapInfo['device']
-            for device in devices:
-                if device == cryptoDev or device.dependsOn(cryptoDev):
-                    keep = True
-                    break
-
-            if not keep:
-                del self.cryptTab.mappings[name]
-
-        return self.cryptTab.crypttab()
-
-    def mdadmConf(self):
-        """ Return the contents of mdadm.conf. """
-        arrays = self.devicetree.getDevicesByType("mdarray")
-        arrays.extend(self.devicetree.getDevicesByType("mdbiosraidarray"))
-        arrays.extend(self.devicetree.getDevicesByType("mdcontainer"))
-        # Sort it, this not only looks nicer, but this will also put
-        # containers (which get md0, md1, etc.) before their members
-        # (which get md127, md126, etc.). and lame as it is mdadm will not
-        # assemble the whole stack in one go unless listed in the proper order
-        # in mdadm.conf
-        arrays.sort(key=lambda d: d.path)
-        if not arrays:
-            return ""
-
-        conf = "# mdadm.conf written out by anaconda\n"
-        conf += "MAILADDR root\n"
-        conf += "AUTO +imsm +1.x -all\n"
-        devices = self.mountpoints.values() + self.swapDevices
-        for array in arrays:
-            for device in devices:
-                if device == array or device.dependsOn(array):
-                    conf += array.mdadmConfEntry
-                    break
-
-        return conf
-
-    def multipathConf(self):
-        """ Return the contents of multipath.conf. """
-        mpaths = self.devicetree.getDevicesByType("dm-multipath")
-        if not mpaths:
-            return None
-        mpaths.sort(key=lambda d: d.name)
-        config = MultipathConfigWriter()
-        whitelist = []
-        for mpath in mpaths:
-            config.addMultipathDevice(mpath)
-            whitelist.append(mpath.name)
-            whitelist.extend([d.name for d in mpath.parents])
-
-        # blacklist everything we're not using and let the
-        # sysadmin sort it out.
-        for d in self.devicetree.devices:
-            if not d.name in whitelist:
-                config.addBlacklistDevice(d)
-
-        return config
-
-    def fstab (self):
-        format = "%-23s %-23s %-7s %-15s %d %d\n"
-        fstab = """
-#
-# /etc/fstab
-# Created by anaconda on %s
-#
-# Accessible filesystems, by reference, are maintained under '/dev/disk'
-# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
-#
-""" % time.asctime()
-
-        devices = sorted(self.mountpoints.values(),
-                         key=lambda d: d.format.mountpoint)
-        devices += self.swapDevices
-        netdevs = self.devicetree.getDevicesByInstance(NetworkStorageDevice)
-        for device in devices:
-            # why the hell do we put swap in the fstab, anyway?
-            if not device.format.mountable and device.format.type != "swap":
-                continue
-
-            # Don't write out lines for optical devices, either.
-            if isinstance(device, OpticalDevice):
-                continue
-
-            fstype = getattr(device.format, "mountType", device.format.type)
-            if fstype == "swap":
-                mountpoint = "swap"
-                options = device.format.options
-            else:
-                mountpoint = device.format.mountpoint
-                options = device.format.options
-                if not mountpoint:
-                    log.warning("%s filesystem on %s has no mountpoint" % \
-                                                            (fstype,
-                                                             device.path))
-                    continue
-
-            options = options or "defaults"
-            for netdev in netdevs:
-                if device.dependsOn(netdev):
-                    options = options + ",_netdev"
-                    break
-            if device.encrypted:
-                options += ",x-systemd.device-timeout=0"
-            devspec = device.fstabSpec
-            dump = device.format.dump
-            if device.format.check and mountpoint == "/":
-                passno = 1
-            elif device.format.check:
-                passno = 2
-            else:
-                passno = 0
-            fstab = fstab + device.fstabComment
-            fstab = fstab + format % (devspec, mountpoint, fstype,
-                                      options, dump, passno)
-
-        # now, write out any lines we were unable to process because of
-        # unrecognized filesystems or unresolveable device specifications
-        for line in self.preserveLines:
-            fstab += line
-
-        return fstab
-
-
-def getReleaseString():
-    relName = None
-    relVer = None
-
-    try:
-        relArch = util.capture_output(["arch"], root=ROOT_PATH).strip()
-    except:
-        relArch = None
-
-    filename = "%s/etc/redhat-release" % ROOT_PATH
-    if os.access(filename, os.R_OK):
-        with open(filename) as f:
-            try:
-                relstr = f.readline().strip()
-            except (IOError, AttributeError):
-                relstr = ""
-
-        # get the release name and version
-        # assumes that form is something
-        # like "Red Hat Linux release 6.2 (Zoot)"
-        (product, sep, version) = relstr.partition(" release ")
-        if sep:
-            relName = product
-            relVer = version.split()[0]
-
-    return (relArch, relName, relVer)
-
-def findExistingInstallations(devicetree):
-    if not os.path.exists(ROOT_PATH):
-        util.makedirs(ROOT_PATH)
-
-    roots = []
-    for device in devicetree.leaves:
-        if not device.format.linuxNative or not device.format.mountable or \
-           not device.controllable:
-            continue
-
-        try:
-            device.setup()
-        except Exception as e:
-            log.warning("setup of %s failed: %s" % (device.name, e))
-            continue
-
-        options = device.format.options + ",ro"
-        try:
-            device.format.mount(options=options, mountpoint=ROOT_PATH)
-        except Exception as e:
-            log.warning("mount of %s as %s failed: %s" % (device.name,
-                                                          device.format.type,
-                                                          e))
-            device.teardown()
-            continue
-
-        if not os.access(ROOT_PATH + "/etc/fstab", os.R_OK):
-            device.teardown(recursive=True)
-            continue
-
-        try:
-            (arch, product, version) = getReleaseString()
-        except ValueError:
-            name = _("Linux on %s") % device.name
-        else:
-            # I'd like to make this finer grained, but it'd be very difficult
-            # to translate.
-            if not product or not version or not arch:
-                name = _("Unknown Linux")
-            else:
-                name = _("%(product)s Linux %(version)s for %(arch)s") % \
-                        {"product": product, "version": version, "arch": arch}
-
-        (mounts, swaps) = parseFSTab(devicetree, chroot=ROOT_PATH)
-        device.teardown()
-        if not mounts and not swaps:
-            # empty /etc/fstab. weird, but I've seen it happen.
-            continue
-        roots.append(Root(mounts=mounts, swaps=swaps, name=name))
-
-    return roots
-
-class Root(object):
-    def __init__(self, mounts=None, swaps=None, name=None):
-        # mountpoint key, StorageDevice value
-        if not mounts:
-            self.mounts = {}
-        else:
-            self.mounts = mounts
-
-        # StorageDevice
-        if not swaps:
-            self.swaps = []
-        else:
-            self.swaps = swaps
-
-        self.name = name    # eg: "Fedora Linux 16 for x86_64", "Linux on sda2"
-
-        if not self.name and "/" in self.mounts:
-            self.name = self.mounts["/"].format.uuid
-
-    @property
-    def device(self):
-        return self.mounts.get("/")
-
-def parseFSTab(devicetree, chroot=None):
-    """ parse /etc/fstab and return a tuple of a mount dict and swap list """
-    if not chroot or not os.path.isdir(chroot):
-        chroot = ROOT_PATH
-
-    mounts = {}
-    swaps = []
-    path = "%s/etc/fstab" % chroot
-    if not os.access(path, os.R_OK):
-        # XXX should we raise an exception instead?
-        log.info("cannot open %s for read" % path)
-        return (mounts, swaps)
-
-    blkidTab = BlkidTab(chroot=chroot)
-    try:
-        blkidTab.parse()
-        log.debug("blkid.tab devs: %s" % blkidTab.devices.keys())
-    except Exception as e:
-        log.info("error parsing blkid.tab: %s" % e)
-        blkidTab = None
-
-    cryptTab = CryptTab(devicetree, blkidTab=blkidTab, chroot=chroot)
-    try:
-        cryptTab.parse(chroot=chroot)
-        log.debug("crypttab maps: %s" % cryptTab.mappings.keys())
-    except Exception as e:
-        log.info("error parsing crypttab: %s" % e)
-        cryptTab = None
-
-    with open(path) as f:
-        log.debug("parsing %s" % path)
-        for line in f.readlines():
-            # strip off comments
-            (line, pound, comment) = line.partition("#")
-            fields = line.split(None, 4)
-
-            if len(fields) < 5:
-                continue
-
-            (devspec, mountpoint, fstype, options, rest) = fields
-
-            # find device in the tree
-            device = devicetree.resolveDevice(devspec,
-                                              cryptTab=cryptTab,
-                                              blkidTab=blkidTab,
-                                              options=options)
-
-            if device is None:
-                continue
-
-            if fstype != "swap":
-                mounts[mountpoint] = device
-            else:
-                swaps.append(device)
-
-    return (mounts, swaps)
-
-
-class DeviceFactory(object):
-    type_desc = None
-    member_format = None        # format type for member devices
-    new_container_attr = None   # name of Storage method to create a container
-    new_device_attr = None      # name of Storage method to create a device
-    container_list_attr = None  # name of Storage attribute to list containers
-    encrypt_members = False
-    encrypt_leaves = True
-
-    def __init__(self, storage, size, disks, raid_level, encrypted):
-        self.storage = storage          # the Storage instance
-        self.size = size                # the requested size for this device
-        self.disks = disks              # the set of disks to allocate from
-        self.raid_level = raid_level
-        self.encrypted = encrypted
-
-        # this is a list of member devices, used to short-circuit the logic in
-        # setContainerMembers for case of a partition
-        self.member_list = None
-
-        # choose a size set class for member partition allocation
-        if raid_level is not None and raid_level.startswith("raid"):
-            self.set_class = SameSizeSet
-        else:
-            self.set_class = TotalSizeSet
-
-    @property
-    def container_list(self):
-        """ A list of containers of the type used by this device. """
-        if not self.container_list_attr:
-            return []
-
-        return getattr(self.storage, self.container_list_attr)
-
-    def new_container(self, *args, **kwargs):
-        """ Return the newly created container for this device. """
-        return getattr(self.storage, self.new_container_attr)(*args, **kwargs)
-
-    def new_device(self, *args, **kwargs):
-        """ Return the newly created device. """
-        return getattr(self.storage, self.new_device_attr)(*args, **kwargs)
-
-    def post_create(self):
-        """ Perform actions required after device creation. """
-        pass
-
-    def container_size_func(self, container, device=None):
-        """ Return the total space needed for the specified container. """
-        size = container.size
-        size += self.device_size
-        if device:
-            size -= device.size
-
-        return size
-
-    @property
-    def device_size(self):
-        """ The total disk space required for this device. """
-        return self.size
-
-    def set_device_size(self, container, device=None):
-        return self.size
-
-class DiskFactory(DeviceFactory):
-    type_desc = "disk"
-    # this is to protect against changes to these settings in the base class
-    encrypt_members = False
-    encrypt_leaves = True
-
-class PartitionFactory(DeviceFactory):
-    type_desc = "partition"
-    new_device_attr = "newPartition"
-    default_size = 1
-
-    def __init__(self, storage, size, disks, raid_level, encrypted):
-        super(PartitionFactory, self).__init__(storage, size, disks, raid_level,
-                                               encrypted)
-        self.member_list = self.disks
-
-    def new_device(self, *args, **kwargs):
-        grow = True
-        max_size = kwargs.pop("size")
-        kwargs["size"] = 1
-
-        device = self.storage.newPartition(*args,
-                                           grow=grow, maxsize=max_size,
-                                           **kwargs)
-        return device
-
-    def post_create(self):
-        self.storage.allocatePartitions()
-
-    def set_device_size(self, container, device=None):
-        size = self.size
-        if device:
-            if size != device.size:
-                log.info("adjusting device size from %.2f to %.2f"
-                                % (device.size, size))
-
-            base_size = max(PartitionFactory.default_size,
-                            device.format.minSize)
-            size = max(base_size, size)
-            device.req_base_size = base_size
-            device.req_size = base_size
-            device.req_max_size = size
-            device.req_grow = size > base_size
-
-            # this probably belongs somewhere else but this is our chance to
-            # update the disk set
-            device.req_disks = self.disks[:]
-
-        return size
-
-class BTRFSFactory(DeviceFactory):
-    type_desc = "btrfs"
-    member_format = "btrfs"
-    new_container_attr = "newBTRFS"
-    new_device_attr = "newBTRFSSubVolume"
-    container_list_attr = "btrfsVolumes"
-    encrypt_members = True
-    encrypt_leaves = False
-
-    def __init__(self, storage, size, disks, raid_level, encrypted):
-        super(BTRFSFactory, self).__init__(storage, size, disks, raid_level,
-                                           encrypted)
-        self.raid_level = raid_level or "single"
-
-    def new_container(self, *args, **kwargs):
-        """ Return the newly created container for this device. """
-        kwargs["dataLevel"] = self.raid_level
-        return getattr(self.storage, self.new_container_attr)(*args, **kwargs)
-
-    def container_size_func(self, container, device=None):
-        """ Return the total space needed for the specified container. """
-        if container.exists:
-            container_size = container.size
-        else:
-            container_size = sum([s.req_size for s in container.subvolumes])
-
-        if device:
-            size = self.device_size
-        else:
-            size = container_size + self.device_size
-
-        return size
-
-    @property
-    def device_size(self):
-        # until we get/need something better
-        if self.raid_level in ("single", "raid0"):
-            return self.size
-        elif self.raid_level in ("raid1", "raid10"):
-            return self.size * len(self.disks)
-
-    def new_device(self, *args, **kwargs):
-        kwargs["dataLevel"] = self.raid_level
-        kwargs["metaDataLevel"] = self.raid_level
-        return super(BTRFSFactory, self).new_device(*args, **kwargs)
-
-class LVMFactory(DeviceFactory):
-    type_desc = "lvm"
-    member_format = "lvmpv"
-    new_container_attr = "newVG"
-    new_device_attr = "newLV"
-    container_list_attr = "vgs"
-    encrypt_members = True
-    encrypt_leaves = False
-
-    @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)
-
-    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))
-
-        return size
-
-    def set_device_size(self, container, device=None):
-        size = self.size
-        free = container.freeSpace
-        if device:
-            free += device.size
-
-        if free < size:
-            log.info("adjusting device size from %.2f to %.2f so it fits "
-                     "in container" % (size, free))
-            size = free
-
-        if device:
-            if size != device.size:
-                log.info("adjusting device size from %.2f to %.2f"
-                                % (device.size, size))
-
-            device.size = size
-
-        return size
-
-class MDFactory(DeviceFactory):
-    type_desc = "md"
-    member_format = "mdmember"
-    new_container_attr = None
-    new_device_attr = "newMDArray"
-
-    @property
-    def container_list(self):
-        return []
-
-    @property
-    def device_size(self):
-        return get_member_space(self.size, len(self.disks),
-                                level=self.raid_level)
-
-    def container_size_func(self, container, device=None):
-        return get_member_space(self.size, len(container.parents),
-                                level=self.raid_level)
-
-    def new_device(self, *args, **kwargs):
-        kwargs["level"] = self.raid_level
-        kwargs["totalDevices"] = len(kwargs.get("parents"))
-        kwargs["memberDevices"] = len(kwargs.get("parents"))
-        return super(MDFactory, self).new_device(*args, **kwargs)
diff --git a/pyanaconda/storage/arch.py b/pyanaconda/storage/arch.py
deleted file mode 100644
index 7fc39e7..0000000
--- a/pyanaconda/storage/arch.py
+++ /dev/null
@@ -1,315 +0,0 @@
-#
-# arch.py
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2013
-# Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@redhat.com>
-#            Paul Nasrat <pnasrat@redhat.com>
-#            Peter Jones <pjones@redhat.com>
-#            Chris Lumens <clumens@redhat.com>
-#            Will Woods <wwoods@redhat.com>
-#            Dennis Gilmore <dgilmore@ausil.us>
-#            David Marlin <dmarlin@redhat.com>
-#
-
-import os
-
-from .flags import flags
-
-## Get the SPARC machine variety type.
-# @return The SPARC machine type, or 0 if not SPARC.
-def getSparcMachine():
-    if not isSparc():
-        return 0
-
-    machine = None
-
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-        if line.find('type') != -1:
-            machine = line.split(':')[1].strip()
-            return machine
-
-    return None
-
-## Get the PPC machine variety type.
-# @return The PPC machine type, or 0 if not PPC.
-def getPPCMachine():
-    if not isPPC():
-        return 0
-
-    ppcMachine = None
-    machine = None
-    platform = None
-
-    # ppc machine hash
-    ppcType = { 'Mac'      : 'PMac',
-                'Book'     : 'PMac',
-                'CHRP IBM' : 'pSeries',
-                'Pegasos'  : 'Pegasos',
-                'Efika'    : 'Efika',
-                'iSeries'  : 'iSeries',
-                'pSeries'  : 'pSeries',
-                'PReP'     : 'PReP',
-                'CHRP'     : 'pSeries',
-                'Amiga'    : 'APUS',
-                'Gemini'   : 'Gemini',
-                'Shiner'   : 'ANS',
-                'BRIQ'     : 'BRIQ',
-                'Teron'    : 'Teron',
-                'AmigaOne' : 'Teron',
-                'Maple'    : 'pSeries',
-                'Cell'     : 'pSeries',
-                'Momentum' : 'pSeries',
-                'PS3'      : 'PS3',
-                'PowerNV'  : 'pSeries'
-                }
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-        if line.find('machine') != -1:
-            machine = line.split(':')[1]
-        elif line.find('platform') != -1:
-            platform = line.split(':')[1]
-
-    for part in (machine, platform):
-        if ppcMachine is None and part is not None:
-            for type in ppcType.items():
-                if part.find(type[0]) != -1:
-                    ppcMachine = type[1]
-
-    if ppcMachine is None:
-        log.warning("Unable to find PowerPC machine type")
-    elif ppcMachine == 0:
-        log.warning("Unknown PowerPC machine type: %s" %(ppcMachine,))
-
-    return ppcMachine
-
-## Get the powermac machine ID.
-# @return The powermac machine id, or 0 if not PPC.
-def getPPCMacID():
-    machine = None
-
-    if not isPPC():
-        return 0
-    if getPPCMachine() != "PMac":
-        return 0
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-      if line.find('machine') != -1:
-        machine = line.split(':')[1]
-        machine = machine.strip()
-        return machine
-
-    log.warning("No Power Mac machine id")
-    return 0
-
-## Get the powermac generation.
-# @return The powermac generation, or 0 if not powermac.
-def getPPCMacGen():
-    # XXX: should NuBus be here?
-    pmacGen = ['OldWorld', 'NewWorld', 'NuBus']
-
-    if not isPPC():
-        return 0
-    if getPPCMachine() != "PMac":
-        return 0
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    gen = None
-    for line in lines:
-      if line.find('pmac-generation') != -1:
-        gen = line.split(':')[1]
-        break
-
-    if gen is None:
-        log.warning("Unable to find pmac-generation")
-
-    for _type in pmacGen:
-      if _type in gen:
-          return type
-
-    log.warning("Unknown Power Mac generation: %s" %(gen,))
-    return 0
-
-## Determine if the hardware is an iBook or PowerBook
-# @return 1 if so, 0 otherwise.
-def getPPCMacBook():
-    if not isPPC():
-        return 0
-    if getPPCMachine() != "PMac":
-        return 0
-
-    f = open('/proc/cpuinfo', 'r')
-    buf = f.read()
-    f.close()
-    return 'book' in buf.lower()
-
-## Get the ARM processor variety.
-# @return The ARM processor variety type, or 0 if not ARM.
-def getARMMachine():
-    if not isARM():
-        return 0
-
-    if flags.arm_platform:
-        return flags.arm_platform
-
-    armMachine = os.uname()[2].rpartition('.' )[2]
-
-    if armMachine.startswith('arm'):
-        return None
-    else:
-        return armMachine
-
-
-cell = None
-## Determine if the hardware is the Cell platform.
-# @return True if so, False otherwise.
-def isCell():
-    global cell
-    if cell is not None:
-        return cell
-
-    cell = False
-    if not isPPC():
-        return cell
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-
-    for line in lines:
-      if 'Cell' in line:
-          cell = True
-
-    return cell
-
-mactel = None
-## Determine if the hardware is an Intel-based Apple Mac.
-# @return True if so, False otherwise.
-def isMactel():
-    global mactel
-    if mactel is not None:
-        return mactel
-
-    if not isX86():
-        mactel = False
-    elif not os.path.isfile(DMI_CHASSIS_VENDOR):
-        mactel = False
-    else:
-        buf = open(DMI_CHASSIS_VENDOR).read()
-        mactel = ("apple" in buf.lower())
-    return mactel
-
-efi = None
-## Determine if the hardware supports EFI.
-# @return True if so, False otherwise.
-def isEfi():
-    global efi
-    if efi is not None:
-        return efi
-
-    efi = False
-    # XXX need to make sure efivars is loaded...
-    if os.path.exists("/sys/firmware/efi"):
-        efi = True
-
-    return efi
-
-# Architecture checking functions
-
-def isX86(bits=None):
-    arch = os.uname()[4]
-
-    # x86 platforms include:
-    #     i*86
-    #     athlon*
-    #     x86_64
-    #     amd*
-    #     ia32e
-    if bits is None:
-        if (arch.startswith('i') and arch.endswith('86')) or \
-           arch.startswith('athlon') or arch.startswith('amd') or \
-           arch == 'x86_64' or arch == 'ia32e':
-            return True
-    elif bits == 32:
-        if arch.startswith('i') and arch.endswith('86'):
-            return True
-    elif bits == 64:
-        if arch.startswith('athlon') or arch.startswith('amd') or \
-           arch == 'x86_64' or arch == 'ia32e':
-            return True
-
-    return False
-
-def isPPC(bits=None):
-    arch = os.uname()[4]
-
-    if bits is None:
-        if arch == 'ppc' or arch == 'ppc64':
-            return True
-    elif bits == 32:
-        if arch == 'ppc':
-            return True
-    elif bits == 64:
-        if arch == 'ppc64':
-            return True
-
-    return False
-
-def isS390():
-    return os.uname()[4].startswith('s390')
-
-def isIA64():
-    return os.uname()[4] == 'ia64'
-
-def isAlpha():
-    return os.uname()[4].startswith('alpha')
-
-def isSparc():
-    return os.uname()[4].startswith('sparc')
-
-def isARM():
-    return os.uname()[4].startswith('arm')
-
-def getArch():
-    if isX86(bits=32):
-        return 'i386'
-    elif isX86(bits=64):
-        return 'x86_64'
-    elif isPPC(bits=32):
-        return 'ppc'
-    elif isPPC(bits=64):
-        return 'ppc64'
-    elif isAlpha():
-        return 'alpha'
-    elif isSparc():
-        return 'sparc'
-    elif isARM():
-        return 'arm'
-    else:
-        return os.uname()[4]
diff --git a/pyanaconda/storage/dasd.py b/pyanaconda/storage/dasd.py
deleted file mode 100644
index bd3d4de..0000000
--- a/pyanaconda/storage/dasd.py
+++ /dev/null
@@ -1,218 +0,0 @@
-#
-# dasd.py - DASD class
-#
-# Copyright (C) 2009, 2010  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Red Hat Author(s): David Cantrell <dcantrell@redhat.com>
-#
-
-import sys
-import os
-from pyanaconda.storage.errors import DasdFormatError
-from pyanaconda.storage.devices import deviceNameToDiskByPath
-from pyanaconda.storage import util
-from pyanaconda.storage import arch
-from . import ROOT_PATH
-from .udev import udev_trigger
-
-import logging
-log = logging.getLogger("storage")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-def getDasdPorts():
-    """ Return comma delimited string of valid DASD ports. """
-    ports = []
-
-    f = open("/proc/dasd/devices", "r")
-    lines = map(lambda x: x.strip(), f.readlines())
-    f.close()
-
-    for line in lines:
-        if "unknown" in line:
-            continue
-
-        if "(FBA )" in line or "(ECKD)" in line:
-            ports.append(line.split('(')[0])
-
-    return ','.join(ports)
-
-class DASD:
-    """ Controlling class for DASD interaction before the storage code in
-        anaconda has initialized.
-
-        The DASD class can determine if any DASD devices on the system are
-        unformatted and can perform a dasdfmt on them.
-    """
-
-    def __init__(self):
-        self._dasdlist = []
-        self._devices = []                  # list of DASDDevice objects
-        self.totalCylinders = 0
-        self._completedCylinders = 0.0
-        self._maxFormatJobs = 0
-        self.dasdfmt = "/sbin/dasdfmt"
-        self.commonArgv = ["-y", "-d", "cdl", "-b", "4096"]
-        self.started = False
-
-    def __call__(self):
-        return self
-
-    def startup(self, intf, exclusiveDisks, zeroMbr):
-        """ Look for any unformatted DASDs in the system and offer the user
-            the option for format them with dasdfmt or exit the installer.
-        """
-        if self.started:
-            return
-
-        self.started = True
-
-        if not arch.isS390():
-            return
-
-        # Trigger udev data about the dasd devices on the system
-        udev_trigger(action="change", name="dasd*")
-
-        log.info("Checking for unformatted DASD devices:")
-
-        for device in os.listdir("/sys/block"):
-            if not device.startswith("dasd"):
-                continue
-
-            statusfile = "/sys/block/%s/device/status" % (device,)
-            if not os.path.isfile(statusfile):
-                continue
-
-            f = open(statusfile, "r")
-            status = f.read().strip()
-            f.close()
-
-            if status in ["unformatted"] and device not in exclusiveDisks:
-                bypath = deviceNameToDiskByPath(device)
-                if not bypath:
-                    bypath = "/dev/" + device
-
-                log.info("    %s (%s) status is %s, needs dasdfmt" % (device,
-                                                                      bypath,
-                                                                      status,))
-                self._dasdlist.append((device, bypath))
-
-        if not len(self._dasdlist):
-            log.info("    no unformatted DASD devices found")
-            return
-
-        askUser = True
-
-        if zeroMbr:
-            askUser = False
-        elif not intf and not zeroMbr:
-            log.info("    non-interactive kickstart install without zerombr "
-                     "command, unable to run dasdfmt, exiting installer")
-            sys.exit(0)
-
-        c = len(self._dasdlist)
-
-        if intf and askUser:
-            devs = ''
-            for dasd, bypath in self._dasdlist:
-                devs += "%s\n" % (bypath,)
-
-            rc = intf.questionInitializeDASD(c, devs)
-            if rc == 1:
-                log.info("    not running dasdfmt, continuing installation")
-                return
-
-        # gather total cylinder count
-        argv = ["-t", "-v"] + self.commonArgv
-        for dasd, bypath in self._dasdlist:
-            buf = util.capture_output([self.dasdfmt, argv, "/dev/" + dasd])
-            for line in buf.splitlines():
-                if line.startswith("Drive Geometry: "):
-                    # line will look like this:
-                    # Drive Geometry: 3339 Cylinders * 15 Heads =  50085 Tracks
-                    cyls = long(filter(lambda s: s, line.split(' '))[2])
-                    self.totalCylinders += cyls
-                    break
-
-        # format DASDs
-        argv = ["-P"] + self.commonArgv
-        update = self._updateProgressWindow
-
-        title = P_("Formatting DASD Device", "Formatting DASD Devices", c)
-        msg = P_("Preparing %d DASD device for use with Linux..." % c,
-                 "Preparing %d DASD devices for use with Linux..." % c, c)
-
-        if intf:
-            if self.totalCylinders:
-                pw = intf.progressWindow(title, msg, 1.0)
-            else:
-                pw = intf.progressWindow(title, msg, 100, pulse=True)
-
-        for dasd, bypath in self._dasdlist:
-            log.info("Running dasdfmt on %s" % (bypath,))
-            arglist = argv + ["/dev/" + dasd]
-
-            try:
-                rc = util.run_program([self.dasdfmt] + arglist)
-            except Exception as e:
-                raise DasdFormatError(e, bypath)
-
-            if rc:
-                raise DasdFormatError("dasdfmt failed: %s" % rc, bypath)
-
-        if intf:
-            pw.pop()
-
-    def addDASD(self, dasd):
-        """ Adds a DASDDevice to the internal list of DASDs. """
-        if dasd:
-            self._devices.append(dasd)
-
-    def clear_device_list(self):
-        """ Clear the device list to force re-populate on next access. """
-        self._devices = []
-
-    def write(self):
-        """ Write /etc/dasd.conf to target system for all DASD devices
-            configured during installation.
-        """
-        if self._devices == []:
-            return
-
-        f = open(os.path.realpath(ROOT_PATH + "/etc/dasd.conf"), "w")
-        for dasd in self._devices:
-            fields = [dasd.busid] + dasd.getOpts()
-            f.write("%s\n" % (" ".join(fields),))
-        f.close()
-
-    def _updateProgressWindow(self, data, callback_data=None):
-        """ Reads progress output from dasdfmt and collects the number of
-            cylinders completed so the progress window can update.
-        """
-        if not callback_data:
-            return
-
-        if data == '\n':
-            # each newline we see in this output means one more cylinder done
-            self._completedCylinders += 1.0
-            callback_data.set(self._completedCylinders / self.totalCylinders)
-
-# Create DASD singleton
-DASD = DASD()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/storage/deviceaction.py b/pyanaconda/storage/deviceaction.py
deleted file mode 100644
index c8f96f2..0000000
--- a/pyanaconda/storage/deviceaction.py
+++ /dev/null
@@ -1,587 +0,0 @@
-# deviceaction.py
-# Device modification action classes for anaconda's storage configuration
-# module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-from udev import *
-import math
-
-from devices import StorageDevice
-from devices import PartitionDevice
-from devices import LVMLogicalVolumeDevice
-from formats import getFormat
-from errors import *
-from parted import partitionFlag, PARTITION_LBA
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-from contextlib import contextmanager
-
-@contextmanager
-def progress_report_stub(message):
-    yield
-
-try:
-    from pyanaconda.progress import progress_report
-except ImportError:
-    progress_report = progress_report_stub
-
-# The values are just hints as to the ordering.
-# Eg: fsmod and devmod ordering depends on the mod (shrink -v- grow)
-ACTION_TYPE_NONE = 0
-ACTION_TYPE_DESTROY = 1000
-ACTION_TYPE_RESIZE = 500
-ACTION_TYPE_CREATE = 100
-
-action_strings = {ACTION_TYPE_NONE: "None",
-                  ACTION_TYPE_DESTROY: "Destroy",
-                  ACTION_TYPE_RESIZE: "Resize",
-                  ACTION_TYPE_CREATE: "Create"}
-
-ACTION_OBJECT_NONE = 0
-ACTION_OBJECT_FORMAT = 1
-ACTION_OBJECT_DEVICE = 2
-
-object_strings = {ACTION_OBJECT_NONE: "None",
-                  ACTION_OBJECT_FORMAT: "Format",
-                  ACTION_OBJECT_DEVICE: "Device"}
-
-RESIZE_SHRINK = 88
-RESIZE_GROW = 89
-
-resize_strings = {RESIZE_SHRINK: "Shrink",
-                  RESIZE_GROW: "Grow"}
-
-def action_type_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in action_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-    return resize_type_from_string(type_string)
-
-def action_object_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in object_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-def resize_type_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in resize_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-class DeviceAction(object):
-    """ An action that will be carried out in the future on a Device.
-
-        These classes represent actions to be performed on devices or
-        filesystems.
-
-        The operand Device instance will be modified according to the
-        action, but no changes will be made to the underlying device or
-        filesystem until the DeviceAction instance's execute method is
-        called. The DeviceAction instance's cancel method should reverse
-        any modifications made to the Device instance's attributes.
-
-        If the Device instance represents a pre-existing device, the
-        constructor should call any methods or set any attributes that the
-        action will eventually change. Device/DeviceFormat classes should verify
-        that the requested modifications are reasonable and raise an
-        exception if not.
-
-        Only one action of any given type/object pair can exist for any
-        given device at any given time. This is enforced by the
-        DeviceTree.
-
-        Basic usage:
-
-            a = DeviceAction(dev)
-            a.execute()
-
-            OR
-
-            a = DeviceAction(dev)
-            a.cancel()
-
-
-        XXX should we back up the device with a deep copy for forcibly
-            cancelling actions?
-
-            The downside is that we lose any checking or verification that
-            would get done when resetting the Device instance's attributes to
-            their original values.
-
-            The upside is that we would be guaranteed to achieve a total
-            reversal. No chance of, eg: resizes ending up altering Device
-            size due to rounding or other miscalculation.
-"""
-    type = ACTION_TYPE_NONE
-    obj = ACTION_OBJECT_NONE
-    _id = 0
-
-    def __init__(self, device):
-        if not isinstance(device, StorageDevice):
-            raise ValueError("arg 1 must be a StorageDevice instance")
-        self.device = device
-
-        # Establish a unique id for each action instance. Making shallow or
-        # deep copyies of DeviceAction instances will require __copy__ and
-        # __deepcopy__ methods to handle incrementing the id in the copy
-        self.id = DeviceAction._id
-        DeviceAction._id += 1
-
-    def execute(self):
-        """ perform the action """
-        pass
-
-    def cancel(self):
-        """ cancel the action """
-        pass
-
-    @property
-    def isDestroy(self):
-        return self.type == ACTION_TYPE_DESTROY
-
-    @property
-    def isCreate(self):
-        return self.type == ACTION_TYPE_CREATE
-
-    @property
-    def isResize(self):
-        return self.type == ACTION_TYPE_RESIZE
-
-    @property
-    def isShrink(self):
-        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_SHRINK)
-
-    @property
-    def isGrow(self):
-        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_GROW)
-
-    @property
-    def isDevice(self):
-        return self.obj == ACTION_OBJECT_DEVICE
-
-    @property
-    def isFormat(self):
-        return self.obj == ACTION_OBJECT_FORMAT
-
-    @property
-    def format(self):
-        return self.device.format
-
-    def __str__(self):
-        s = "[%d] %s %s" % (self.id, action_strings[self.type],
-                            object_strings[self.obj])
-        if self.isResize:
-            s += " (%s)" % resize_strings[self.dir]
-        if self.isFormat:
-            s += " %s on" % self.format.desc
-        s += " %s %s (id %d)" % (self.device.type, self.device.name,
-                                 self.device.id)
-        return s
-
-    def requires(self, action):
-        """ Return True if self requires action. """
-        return False
-
-    def obsoletes(self, action):
-        """ Return True is self obsoletes action.
-
-            DeviceAction instances obsolete other DeviceAction instances with
-            lower id and same device.
-        """
-        return (self.device.id == action.device.id and
-                self.type == action.type and
-                self.obj == action.obj and
-                self.id > action.id)
-
-
-class ActionCreateDevice(DeviceAction):
-    """ Action representing the creation of a new device. """
-    type = ACTION_TYPE_CREATE
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, device):
-        if device.exists:
-            raise ValueError("device already exists")
-
-        # FIXME: assert device.fs is None
-        DeviceAction.__init__(self, device)
-
-    def execute(self):
-        self.device.create()
-
-    def requires(self, action):
-        """ Return True if self requires action.
-
-            Device create actions require other actions when either of the
-            following is true:
-
-                - this action's device depends on the other action's device
-                - both actions are partition create actions on the same disk
-                  and this partition has a higher number
-        """
-        rc = False
-        if self.device.dependsOn(action.device):
-            rc = True
-        elif (action.isCreate and action.isDevice and
-              isinstance(self.device, PartitionDevice) and
-              isinstance(action.device, PartitionDevice) and
-              self.device.disk == action.device.disk):
-            # create partitions in ascending numerical order
-            selfNum = self.device.partedPartition.number
-            otherNum = action.device.partedPartition.number
-            if selfNum > otherNum:
-                rc = True
-        elif (action.isCreate and action.isDevice and
-              isinstance(self.device, LVMLogicalVolumeDevice) and
-              isinstance(action.device, LVMLogicalVolumeDevice) and
-              self.device.vg == action.device.vg and
-              action.device.singlePV and not self.device.singlePV):
-            rc = True
-        return rc
-
-
-class ActionDestroyDevice(DeviceAction):
-    """ An action representing the deletion of an existing device. """
-    type = ACTION_TYPE_DESTROY
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, device):
-        # XXX should we insist that device.fs be None?
-        DeviceAction.__init__(self, device)
-        if device.exists:
-            device.teardown()
-
-    def execute(self):
-        self.device.destroy()
-
-        # Make sure libparted does not keep cached info for this device
-        # and returns it when we create a new device with the same name
-        if self.device.partedDevice:
-            try:
-                self.device.partedDevice.removeFromCache()
-            except Exception:
-                pass
-
-    def requires(self, action):
-        """ Return True if self requires action.
-
-            Device destroy actions require other actions when either of the
-            following is true:
-
-                - the other action's device depends on this action's device
-                - both actions are partition create actions on the same disk
-                  and this partition has a lower number
-        """
-        rc = False
-        if action.device.dependsOn(self.device) and action.isDestroy:
-            rc = True
-        elif (action.isDestroy and action.isDevice and
-              isinstance(self.device, PartitionDevice) and
-              isinstance(action.device, PartitionDevice) and
-              self.device.disk == action.device.disk):
-            # remove partitions in descending numerical order
-            selfNum = self.device.partedPartition.number
-            otherNum = action.device.partedPartition.number
-            if selfNum < otherNum:
-                rc = True
-        elif (action.isDestroy and action.isFormat and
-              action.device.id == self.device.id):
-            # device destruction comes after destruction of device's format
-            rc = True
-        return rc
-
-    def obsoletes(self, action):
-        """ Return True if self obsoletes action.
-
-            - obsoletes all actions w/ lower id that act on the same device,
-              including self, if device does not exist
-
-            - obsoletes all but ActionDestroyFormat actions w/ lower id on the
-              same device if device exists
-        """
-        rc = False
-        if action.device.id == self.device.id:
-            if self.id >= action.id and not self.device.exists:
-                rc = True
-            elif self.id > action.id and \
-                 self.device.exists and \
-                 not (action.isDestroy and action.isFormat):
-                rc = True
-
-        return rc
-
-
-class ActionResizeDevice(DeviceAction):
-    """ An action representing the resizing of an existing device. """
-    type = ACTION_TYPE_RESIZE
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, device, newsize):
-        if not device.resizable:
-            raise ValueError("device is not resizable")
-
-        if long(math.floor(device.currentSize)) == newsize:
-            raise ValueError("new size same as old size")
-
-        DeviceAction.__init__(self, device)
-        if newsize > long(math.floor(device.currentSize)):
-            self.dir = RESIZE_GROW
-        else:
-            self.dir = RESIZE_SHRINK
-        if device.targetSize > 0:
-            self.origsize = device.targetSize
-        else:
-            self.origsize = device.size
-
-        self.device.targetSize = newsize
-
-    def execute(self):
-        self.device.resize()
-
-    def cancel(self):
-        self.device.targetSize = self.origsize
-
-    def requires(self, action):
-        """ Return True if self requires action.
-
-            A device resize action requires another action if:
-
-                - the other action is a format resize on the same device and
-                  both are shrink operations
-                - the other action grows a device (or format it contains) that
-                  this action's device depends on
-                - the other action shrinks a device (or format it contains)
-                  that depends on this action's device
-        """
-        retval = False
-        if action.isResize:
-            if self.device.id == action.device.id and \
-               self.dir == action.dir and \
-               action.isFormat and self.isShrink:
-                retval = True
-            elif action.isGrow and self.device.dependsOn(action.device):
-                retval = True
-            elif action.isShrink and action.device.dependsOn(self.device):
-                retval = True
-
-        return retval
-
-
-class ActionCreateFormat(DeviceAction):
-    """ An action representing creation of a new filesystem. """
-    type = ACTION_TYPE_CREATE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device, format=None):
-        DeviceAction.__init__(self, device)
-        if format:
-            self.origFormat = device.format
-            if self.device.format.exists:
-                self.device.format.teardown()
-            self.device.format = format
-        else:
-            self.origFormat = getFormat(None)
-
-    def execute(self):
-        msg = _("Creating %(type)s on %(device)s") % {"type": self.device.format.type, "device": self.device.path}
-        with progress_report(msg):
-            self.device.setup()
-
-            if isinstance(self.device, PartitionDevice):
-                for flag in partitionFlag.keys():
-                    # Keep the LBA flag on pre-existing partitions
-                    if flag in [ PARTITION_LBA, self.format.partedFlag ]:
-                        continue
-                    self.device.unsetFlag(flag)
-
-                if self.format.partedFlag is not None:
-                    self.device.setFlag(self.format.partedFlag)
-
-                if self.format.partedSystem is not None:
-                    self.device.partedPartition.system = self.format.partedSystem
-
-                self.device.disk.format.commitToDisk()
-
-            self.device.format.create(device=self.device.path,
-                                      options=self.device.formatArgs)
-            # Get the UUID now that the format is created
-            udev_settle()
-            self.device.updateSysfsPath()
-            info = udev_get_block_device(self.device.sysfsPath)
-            self.device.format.uuid = udev_device_get_uuid(info)
-
-    def cancel(self):
-        self.device.format = self.origFormat
-
-    def requires(self, action):
-        """ Return True if self requires action.
-
-            Format create action can require another action if:
-
-                - this action's device depends on the other action's device
-                  and the other action is not a device destroy action
-                - the other action is a create or resize of this action's
-                  device
-        """
-        return ((self.device.dependsOn(action.device) and
-                 not (action.isDestroy and action.isDevice)) or
-                (action.isDevice and (action.isCreate or action.isResize) and
-                 self.device.id == action.device.id))
-
-    def obsoletes(self, action):
-        """ Return True if this action obsoletes action.
-
-            Format create actions obsolete the following actions:
-
-                - format actions w/ lower id on this action's device, other
-                  than those that destroy existing formats
-        """
-        return (self.device.id == action.device.id and
-                self.obj == action.obj and
-                not (action.isDestroy and action.format.exists) and
-                self.id > action.id)
-
-
-class ActionDestroyFormat(DeviceAction):
-    """ An action representing the removal of an existing filesystem. """
-    type = ACTION_TYPE_DESTROY
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device):
-        DeviceAction.__init__(self, device)
-        self.origFormat = self.device.format
-        if device.format.exists:
-            device.format.teardown()
-        self.device.format = None
-
-    def execute(self):
-        """ wipe the filesystem signature from the device """
-        self.device.setup(orig=True)
-        self.format.destroy()
-        udev_settle()
-        self.device.teardown()
-
-    def cancel(self):
-        self.device.format = self.origFormat
-
-    @property
-    def format(self):
-        return self.origFormat
-
-    def requires(self, action):
-        """ Return True if self requires action.
-
-            Format destroy actions require other actions when:
-
-                - the other action's device depends on this action's device
-                  and the other action is a destroy action
-        """
-        return action.device.dependsOn(self.device) and action.isDestroy
-
-    def obsoletes(self, action):
-        """ Return True if this action obsoletes action.
-
-            Format destroy actions obsolete the following actions:
-
-            - format actions w/ lower id on same device, including self if
-              format does not exist
-
-            - format destroy action on a non-existent format shouldn't
-              obsolete a format destroy action on an existing one
-        """
-        return (self.device.id == action.device.id and
-                self.obj == action.obj and
-                (self.id > action.id or
-                 (self.id == action.id and not self.format.exists)) and
-                not (action.format.exists and not self.format.exists))
-
-
-class ActionResizeFormat(DeviceAction):
-    """ An action representing the resizing of an existing filesystem.
-
-        XXX Do we even want to support resizing of a filesystem without
-            also resizing the device it resides on?
-    """
-    type = ACTION_TYPE_RESIZE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device, newsize):
-        if not device.format.resizable:
-            raise ValueError("format is not resizable")
-
-        if long(math.floor(device.format.currentSize)) == newsize:
-            raise ValueError("new size same as old size")
-
-        DeviceAction.__init__(self, device)
-        if newsize > long(math.floor(device.format.currentSize)):
-            self.dir = RESIZE_GROW
-        else:
-            self.dir = RESIZE_SHRINK
-        self.origSize = self.device.format.targetSize
-        self.device.format.targetSize = newsize
-
-    def execute(self):
-        msg = _("Resizing filesystem on %(device)s") % {"device": self.device.path}
-        with progress_report(msg):
-            self.device.setup(orig=True)
-            self.device.format.doResize()
-
-    def cancel(self):
-        self.device.format.targetSize = self.origSize
-
-    def requires(self, action):
-        """ Return True if self requires action.
-
-            A format resize action requires another action if:
-
-                - the other action is a device resize on the same device and
-                  both are grow operations
-                - the other action shrinks a device (or format it contains)
-                  that depends on this action's device
-                - the other action grows a device (or format) that this
-                  action's device depends on
-        """
-        retval = False
-        if action.isResize:
-            if self.device.id == action.device.id and \
-               self.dir == action.dir and \
-               action.isDevice and self.isGrow:
-                retval = True
-            elif action.isShrink and action.device.dependsOn(self.device):
-                retval = True
-            elif action.isGrow and self.device.dependsOn(action.device):
-                retval = True
-
-        return retval
diff --git a/pyanaconda/storage/devicelibs/Makefile.am b/pyanaconda/storage/devicelibs/Makefile.am
deleted file mode 100644
index 86a7d5e..0000000
--- a/pyanaconda/storage/devicelibs/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# storage/devicelibs/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@redhat.com>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storagedevicelibsdir = $(pkgpyexecdir)/storage/devicelibs
-storagedevicelibs_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/storage/devicelibs/__init__.py b/pyanaconda/storage/devicelibs/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/pyanaconda/storage/devicelibs/btrfs.py b/pyanaconda/storage/devicelibs/btrfs.py
deleted file mode 100644
index a6b69e3..0000000
--- a/pyanaconda/storage/devicelibs/btrfs.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#
-# btrfs.py
-# btrfs functions
-#
-# Copyright (C) 2011  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): David Lehman <dlehman@redhat.com>
-#
-
-import os
-import re
-
-from .. import util
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def btrfs(args, capture=False):
-    if capture:
-        exec_func = util.capture_output
-    else:
-        exec_func = util.run_program
-
-    argv = ["btrfs"] + args
-
-    ret = exec_func(argv)
-    if ret and not capture:
-        raise BTRFSError(ret)
-    return ret
-
-def create_volume(devices, label=None, data=None, metadata=None):
-    """ For now, data and metadata must be strings mkfs.btrfs understands. """
-    if not devices:
-        raise ValueError("no devices specified")
-    elif any([not os.path.exists(d) for d in devices]):
-        raise ValueError("one or more specified devices not present")
-
-    args = []
-    if data:
-        args.append("--data=%s" % data)
-
-    if metadata:
-        args.append("--metadata=%s" % metadata)
-
-    if label:
-        args.append("--label=%s" % label)
-
-    args.extend(devices)
-
-    ret = util.run_program(["mkfs.btrfs"] + args)
-    if ret:
-        raise BTRFSError(ret)
-
-    return ret
-
-# destroy is handled using wipefs
-
-# add device
-
-# remove device
-
-def create_subvolume(mountpoint, name):
-    if not os.path.ismount(mountpoint):
-        raise ValueError("volume not mounted")
-
-    path = os.path.normpath("%s/%s" % (mountpoint, name))
-    args = ["subvol", "create", path]
-    return btrfs(args)
-
-def delete_subvolume(mountpoint, name):
-    if not os.path.ismount(mountpoint):
-        raise ValueError("volume not mounted")
-
-    path = os.path.normpath("%s/%s" % (mountpoint, name))
-    args = ["subvol", "delete", path]
-    return btrfs(args)
-
-def create_snapshot(source, dest):
-    pass
-
-def scan_device(path):
-    return btrfs(["device", "scan", path])
-
-# get a list of subvolumes from a mounted btrfs filesystem
-def list_subvolumes(mountpoint):
-    if not os.path.ismount(mountpoint):
-        raise ValueError("volume not mounted")
-
-    args = ["subvol", "list", mountpoint]
-    buf = btrfs(args, capture=True)
-    vols = []
-    for group in re.findall(r'ID (\d+) gen \d+ top level \d+ path (.+)\n', buf):
-        vols.append({"id": int(group[0]), "path": group[1]})
-
-    return vols
diff --git a/pyanaconda/storage/devicelibs/crypto.py b/pyanaconda/storage/devicelibs/crypto.py
deleted file mode 100644
index 2a41cdd..0000000
--- a/pyanaconda/storage/devicelibs/crypto.py
+++ /dev/null
@@ -1,153 +0,0 @@
-#
-# crypto.py
-#
-# Copyright (C) 2009  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@redhat.com>
-#            Martin Sivak <msivak@redhat.com>
-#
-
-import os
-from pycryptsetup import CryptSetup
-
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-LUKS_METADATA_SIZE = 2.0    # MB
-
-# Keep the character set size a power of two to make sure all characters are
-# equally likely
-GENERATED_PASSPHRASE_CHARSET = ("0123456789"
-                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                "abcdefghijklmnopqrstuvwxyz"
-                                "./")
-# 20 chars * 6 bits per char = 120 "bits of security"
-GENERATED_PASSPHRASE_LENGTH = 20
-
-def generateBackupPassphrase():
-    rnd = os.urandom(GENERATED_PASSPHRASE_LENGTH)
-    cs = GENERATED_PASSPHRASE_CHARSET
-    raw = "".join([cs[ord(c) % len(cs)] for c in rnd])
-
-    # Make the result easier to read
-    parts = []
-    for i in xrange(0, len(raw), 5):
-        parts.append(raw[i : i + 5])
-    return "-".join(parts)
-
-def askyes(question):
-    return True
-
-def dolog(priority, text):
-    pass
-
-def askpassphrase(text):
-    return None
-
-def is_luks(device):
-    cs = CryptSetup(device=device, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-    return cs.isLuks()
-
-def luks_uuid(device):
-    cs = CryptSetup(device=device, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-    return cs.luksUUID()
-
-def luks_status(name):
-    """True means active, False means inactive (or non-existent)"""
-    cs = CryptSetup(name=name, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-    return cs.status()
-
-def luks_format(device,
-                passphrase=None,
-                cipher=None, key_size=None, key_file=None):
-    if not passphrase:
-        raise ValueError("luks_format requires passphrase")
-
-    cs = CryptSetup(device=device, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-
-    #None is not considered as default value and pycryptsetup doesn't accept it
-    #so we need to filter out all Nones
-    kwargs = {}
-
-    # Split cipher designator to cipher name and cipher mode
-    cipherType = None
-    cipherMode = None
-    if cipher:
-        cparts = cipher.split("-")
-        cipherType = "".join(cparts[0:1])
-        cipherMode = "-".join(cparts[1:])
-    
-    if cipherType: kwargs["cipher"]  = cipherType
-    if cipherMode: kwargs["cipherMode"]  = cipherMode
-    if   key_size: kwargs["keysize"]  = key_size
-
-    rc = cs.luksFormat(**kwargs)
-    if rc:
-        raise CryptoError("luks_format failed for '%s'" % device)
-
-    # activate first keyslot
-    cs.addKeyByVolumeKey(newPassphrase = passphrase)
-    if rc:
-        raise CryptoError("luks_add_key_by_volume_key failed for '%s'" % device)
-
-
-def luks_open(device, name, passphrase=None, key_file=None):
-    if not passphrase:
-        raise ValueError("luks_format requires passphrase")
-
-    cs = CryptSetup(device=device, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-
-    rc = cs.activate(passphrase = passphrase, name = name)
-    if rc<0:
-        raise CryptoError("luks_open failed for %s (%s) with errno %d" % (device, name, rc))
-
-def luks_close(name):
-    cs = CryptSetup(name=name, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-    rc = cs.deactivate()
-
-    if rc:
-        raise CryptoError("luks_close failed for %s" % name)
-
-def luks_add_key(device,
-                 new_passphrase=None,
-                 passphrase=None, key_file=None):
-
-    if not passphrase:
-        raise ValueError("luks_add_key requires passphrase")
-
-    cs = CryptSetup(device=device, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-    rc = cs.addKeyByPassphrase(passphrase = passphrase, newPassphrase = new_passphrase)
-    
-    if rc<0:
-        raise CryptoError("luks add key failed with errcode %d" % (rc,))
-
-def luks_remove_key(device,
-                    del_passphrase=None,
-                    passphrase=None, key_file=None):
-
-    if not passphrase:
-        raise ValueError("luks_remove_key requires passphrase")
-
-    cs = CryptSetup(device=device, yesDialog = askyes, logFunc = dolog, passwordDialog = askpassphrase)
-    rc = cs.removePassphrase(passphrase = passphrase)
-    
-    if rc:
-        raise CryptoError("luks remove key failed with errcode %d" % (rc,))
-
-
-
diff --git a/pyanaconda/storage/devicelibs/dm.py b/pyanaconda/storage/devicelibs/dm.py
deleted file mode 100644
index e7adfec..0000000
--- a/pyanaconda/storage/devicelibs/dm.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#
-# dm.py
-# device-mapper functions
-#
-# Copyright (C) 2009  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-
-import block
-from .. import util
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def dm_setup(args):
-    ret = util.run_program(["dmsetup"] + args)
-    if ret:
-        raise DMError("Failed to run dmsetup %s" % " ".join(args))
-
-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]
-    dm_setup(args)
-
-def dm_remove(map_name):
-    args = ["remove", map_name]
-    dm_setup(args)
-
-def name_from_dm_node(dm_node):
-    # first, try sysfs
-    name_file = "/sys/class/block/%s/dm/name" % dm_node
-    try:
-        name = open(name_file).read().strip()
-    except IOError:
-        # next, try pyblock
-        name = block.getNameFromDmNode(dm_node)
-
-    return name
-
-def dm_node_from_name(map_name):
-    named_path = "/dev/mapper/%s" % map_name
-    try:
-        # /dev/mapper/ nodes are usually symlinks to /dev/dm-N
-        node = os.path.basename(os.readlink(named_path))
-    except OSError:
-        try:
-            # dm devices' names are based on the block device minor
-            st = os.stat(named_path)
-            minor = os.minor(st.st_rdev)
-            node = "dm-%d" % minor
-        except OSError:
-            # try pyblock
-            node = block.getDmNodeFromName(map_name)
-
-    if not node:
-        raise DMError("dm_node_from_name(%s) has failed." % node)
-
-    return node
diff --git a/pyanaconda/storage/devicelibs/edd.py b/pyanaconda/storage/devicelibs/edd.py
deleted file mode 100644
index 30e8004..0000000
--- a/pyanaconda/storage/devicelibs/edd.py
+++ /dev/null
@@ -1,231 +0,0 @@
-#
-# edd.py
-# BIOS EDD data parsing functions
-#
-# Copyright (C) 2010  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Hans de Goede <hdegoede@redhat.com>
-#            Ales Kozumplik <akozumpl@redhat.com>
-#
-
-import glob
-import logging
-import os
-import re
-import struct
-
-log = logging.getLogger("storage")
-
-re_host_bus = re.compile(r'^PCI\s*(\S*)\s*channel: (\S*)\s*$')
-re_interface_scsi = re.compile(r'^SCSI\s*id: (\S*)\s*lun: (\S*)\s*$')
-re_interface_ata = re.compile(r'^ATA\s*device: (\S*)\s*$')
-
-class EddEntry(object):
-    """ This object merely collects what the /sys/firmware/edd/* entries can
-        provide.
-    """
-    def __init__(self, sysfspath):
-        self.type = None
-
-        self.ata_device = None
-        self.channel = None
-        self.mbr_signature = None
-        self.pci_dev = None
-        self.scsi_id = None
-        self.scsi_lun = None
-        self.sectors = None
-
-        self.load(sysfspath)
-
-    def __str__(self):
-        return \
-            "\ttype: %(type)s, ata_device: %(ata_device)s\n" \
-            "\tchannel: %(channel)s, mbr_signature: %(mbr_signature)s\n" \
-            "\tpci_dev: %(pci_dev)s, scsi_id: %(scsi_id)s\n" \
-            "\tscsi_lun: %(scsi_lun)s, sectors: %(sectors)s" % self.__dict__
-
-    def _read_file(self, filename):
-        contents = None
-        if os.path.exists(filename):
-            with open(filename) as f:
-                contents = f.read().rstrip()
-        return contents
-
-    def load(self, sysfspath):
-        interface = self._read_file(os.path.join(sysfspath, "interface"))
-        if interface:
-            self.type = interface.split()[0]
-            if self.type == "SCSI":
-                match = re_interface_scsi.match(interface)
-                self.scsi_id = int(match.group(1))
-                self.scsi_lun = int(match.group(2))
-            elif self.type == "ATA":
-                match = re_interface_ata.match(interface)
-                self.ata_device = int(match.group(1))
-
-        self.mbr_signature = self._read_file(
-            os.path.join(sysfspath, "mbr_signature"))
-        sectors = self._read_file(os.path.join(sysfspath, "sectors"))
-        if sectors:
-            self.sectors = int(sectors)
-        hbus = self._read_file(os.path.join(sysfspath, "host_bus"))
-        if hbus:
-            match = re_host_bus.match(hbus)
-            if match:
-                self.pci_dev = match.group(1)
-                self.channel = int(match.group(2))
-            else:
-                log.warning("edd: can not match host_bus: %s" % hbus)
-
-class EddMatcher(object):
-    """ This object tries to match given entry to a disk device name.
-
-        Assuming, heuristic analysis and guessing hapens here.
-    """
-    def __init__(self, edd_entry):
-        self.edd = edd_entry
-
-    def devname_from_pci_dev(self):
-        name = None
-        if self.edd.type == "ATA" and \
-                self.edd.channel is not None and \
-                self.edd.ata_device is not None:
-            path = "/sys/devices/pci0000:00/0000:%(pci_dev)s/host%(chan)d/"\
-                "target%(chan)d:0:%(dev)d/%(chan)d:0:%(dev)d:0/block" % {
-                'pci_dev' : self.edd.pci_dev,
-                'chan' : self.edd.channel,
-                'dev' : self.edd.ata_device
-                }
-            if os.path.isdir(path):
-                block_entries = os.listdir(path)
-                if len(block_entries) == 1:
-                    name = block_entries[0]
-            else:
-                log.warning("edd: directory does not exist: %s" % path)
-        elif self.edd.type == "SCSI":
-            pattern = "/sys/devices/pci0000:00/0000:%(pci_dev)s/virtio*/block" % \
-                {'pci_dev' : self.edd.pci_dev}
-            matching_paths = glob.glob(pattern)
-            if len(matching_paths) != 1 or not os.path.exists(matching_paths[0]):
-                return None
-            block_entries = os.listdir(matching_paths[0])
-            if len(block_entries) == 1:
-                name = block_entries[0]
-        return name
-
-    def match_via_mbrsigs(self, mbr_dict):
-        """ Try to match the edd entry based on its mbr signature.
-
-            This will obviously fail for a fresh drive/image, but in extreme
-            cases can also show false positives for randomly matching data.
-        """
-        for (name, mbr_signature) in mbr_dict.items():
-            if mbr_signature == self.edd.mbr_signature:
-                return name
-        return None
-
-def biosdev_to_edd_dir(biosdev):
-    return "/sys/firmware/edd/int13_dev%x" % biosdev
-
-def collect_edd_data():
-    edd_data_dict = {}
-    # the hard drive numbering starts at 0x80 (128 decimal):
-    for biosdev in range(0x80, 0x80+16):
-        sysfspath = biosdev_to_edd_dir(biosdev)
-        if not os.path.exists(sysfspath):
-            break
-        edd_data_dict[biosdev] = EddEntry(sysfspath)
-    return edd_data_dict
-
-def collect_mbrs(devices):
-    """ Read MBR signatures from devices.
-
-        Returns a dict mapping device names to their MBR signatures. It is not
-        guaranteed this will succeed, with a new disk for instance.
-    """
-    mbr_dict = {}
-    for dev in devices:
-        try:
-            fd = os.open(dev.path, os.O_RDONLY)
-            # The signature is the unsigned integer at byte 440:
-            os.lseek(fd, 440, 0)
-            mbrsig = struct.unpack('I', os.read(fd, 4))
-            os.close(fd)
-        except OSError as e:
-            log.warning("edd: error reading mbrsig from disk %s: %s" %
-                        (dev.name, str(e)))
-            continue
-
-        mbrsig_str = "0x%08x" % mbrsig
-        # sanity check
-        if mbrsig_str == '0x00000000':
-            log.info("edd: MBR signature on %s is zero. new disk image?" % dev.name)
-            continue
-        else:
-            for (dev_name, mbrsig_str_old) in mbr_dict.items():
-                if mbrsig_str_old == mbrsig_str:
-                    log.error("edd: dupicite MBR signature %s for %s and %s" %
-                              (mbrsig_str, dev_name, dev.name))
-                    # this actually makes all the other data useless
-                    return {}
-        # update the dictionary
-        mbr_dict[dev.name] = mbrsig_str
-    log.info("edd: collected mbr signatures: %s" % mbr_dict)
-    return mbr_dict
-
-def get_edd_dict(devices):
-    """ Generates the 'device name' -> 'edd number' mapping.
-
-        The EDD kernel module that exposes /sys/firmware/edd is thoroughly
-        broken, the information there is incomplete and sometimes downright
-        wrong. So after we mine out all useful information that the files under
-        /sys/firmware/edd/int13_*/ can provide, we resort to heuristics and
-        guessing. Our first attempt is, by looking at the device type int
-        'interface', attempting to map pci device number, channel number etc. to
-        a sysfs path, check that the path really exists, then read the device
-        name (e.g 'sda') from there. Should this fail we try to match contents
-        of 'mbr_signature' to a real MBR signature found on the existing block
-        devices.
-    """
-    mbr_dict = collect_mbrs(devices)
-    edd_entries_dict = collect_edd_data()
-    global edd_dict
-    for (edd_number, edd_entry) in edd_entries_dict.items():
-        log.debug("edd: data extracted from 0x%x:\n%s" % (edd_number, edd_entry))
-        matcher = EddMatcher(edd_entry)
-        # first try to match through the pci dev etc.
-        name = matcher.devname_from_pci_dev()
-        # next try to compare mbr signatures
-        if name:
-            log.debug("edd: matched 0x%x to %s using pci_dev" % (edd_number, name))
-        else:
-            name = matcher.match_via_mbrsigs(mbr_dict)
-            if name:
-                log.info("edd: matched 0x%x to %s using MBR sig" % (edd_number, name))
-
-        if name:
-            old_edd_number = edd_dict.get(name)
-            if old_edd_number:
-                log.info("edd: both edd entries 0x%x and 0x%x seem to map to %s" %
-                          (old_edd_number, edd_number, name))
-                # this means all the other data can be confused and useless
-                return {}
-            edd_dict[name] = edd_number
-            continue
-        log.error("edd: unable to match edd entry 0x%x" % edd_number)
-    return edd_dict
-
-edd_dict = {}
diff --git a/pyanaconda/storage/devicelibs/loop.py b/pyanaconda/storage/devicelibs/loop.py
deleted file mode 100644
index 8a4750c..0000000
--- a/pyanaconda/storage/devicelibs/loop.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#
-# loop.py
-# loop device functions
-#
-# Copyright (C) 2010  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): David Lehman <dlehman@redhat.com>
-#
-
-import os
-
-from .. import util
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-def losetup(args, capture=False):
-    if capture:
-        exec_func = util.capture_output
-    else:
-        exec_func = util.run_program
-
-    try:
-        # ask losetup what this loop device's backing device is
-        ret = exec_func(["losetup"] + args)
-    except OSError as e:
-        raise LoopError(e.strerror)
-
-    return ret
-
-def get_backing_file(name):
-    path = ""
-    sys_path  = "/sys/class/block/%s/loop/backing_file" % name
-    if os.access(sys_path, os.R_OK):
-        path = open(sys_path).read().strip()
-
-    return path
-
-def get_loop_name(path):
-    args = ["-j", path]
-    buf = losetup(args, capture=True)
-    if len(buf.splitlines()) > 1:
-        # there should never be more than one loop device listed
-        raise LoopError("multiple loops associated with %s" % path)
-
-    name = os.path.basename(buf.split(":")[0])
-    return name
-
-def loop_setup(path):
-    args = ["-f", path]
-    msg = None
-    try:
-        msg = losetup(args)
-    except LoopError as e:
-        msg = str(e)
-
-    if msg:
-        raise LoopError("failed to set up loop for %s: %s" % (path, msg))
-
-def loop_teardown(path):
-    args = ["-d", path]
-    msg = None
-    try:
-        msg = losetup(args)
-    except LoopError as e:
-        msg = str(e)
-
-    if msg:
-        raise DeviceError("failed to tear down loop %s: %s" % (path, msg))
-
-
diff --git a/pyanaconda/storage/devicelibs/lvm.py b/pyanaconda/storage/devicelibs/lvm.py
deleted file mode 100644
index 7691993..0000000
--- a/pyanaconda/storage/devicelibs/lvm.py
+++ /dev/null
@@ -1,403 +0,0 @@
-#
-# lvm.py
-# lvm functions
-#
-# Copyright (C) 2009  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-import math
-import re
-
-import logging
-log = logging.getLogger("storage")
-
-from .. import util
-from .. import arch
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-MAX_LV_SLOTS = 256
-
-# some of lvm's defaults that we have no way to ask it for
-LVM_PE_START = 1.0      # MB
-LVM_PE_SIZE = 4.0       # MB
-
-def has_lvm():
-    if util.find_program_in_path("lvm"):
-        for line in open("/proc/devices").readlines():
-            if "device-mapper" in line.split():
-                return True
-
-    return False
-
-# Start config_args handling code
-#
-# Theoretically we can handle all that can be handled with the LVM --config
-# argument.  For every time we call an lvm_cc (lvm compose config) funciton
-# we regenerate the config_args with all global info.
-config_args = [] # Holds the final argument list
-config_args_data = { "filterRejects": [],    # regular expressions to reject.
-                            "filterAccepts": [] }   # regexp to accept
-
-def _composeConfig():
-    """lvm command accepts lvm.conf type arguments preceded by --config. """
-    global config_args, config_args_data
-    config_args = []
-
-    filter_string = ""
-    rejects = config_args_data["filterRejects"]
-    for reject in rejects:
-        filter_string += ("\"r|/%s$|\"," % reject)
-
-    filter_string = " filter=[%s] " % filter_string.strip(",")
-
-    # As we add config strings we should check them all.
-    if filter_string == "":
-        # Nothing was really done.
-        return
-
-    # devices_string can have (inside the brackets) "dir", "scan",
-    # "preferred_names", "filter", "cache_dir", "write_cache_state",
-    # "types", "sysfs_scan", "md_component_detection".  see man lvm.conf.
-    devices_string = " devices {%s} " % (filter_string) # strings can be added
-    config_string = devices_string # more strings can be added.
-    config_args = ["--config", config_string]
-
-def lvm_cc_addFilterRejectRegexp(regexp):
-    """ Add a regular expression to the --config string."""
-    global config_args_data
-    log.debug("lvm filter: adding %s to the reject list" % regexp)
-    config_args_data["filterRejects"].append(regexp)
-
-    # compose config once more.
-    _composeConfig()
-
-def lvm_cc_removeFilterRejectRegexp(regexp):
-    """ Remove a regular expression from the --config string."""
-    global config_args_data
-    log.debug("lvm filter: removing %s from the reject list" % regexp)
-    try:
-        config_args_data["filterRejects"].remove(regexp)
-    except ValueError:
-        log.debug("%s wasn't in the reject list" % regexp)
-        return
-
-    # compose config once more.
-    _composeConfig()
-
-def lvm_cc_resetFilter():
-    global config_args, config_args_data
-    config_args_data["filterRejects"] = []
-    config_args_data["filterAccepts"] = []
-    config_args = []
-# End config_args handling code.
-
-# Names that should not be used int the creation of VGs
-lvm_vg_blacklist = []
-def blacklistVG(name):
-    global lvm_vg_blacklist
-    lvm_vg_blacklist.append(name)
-
-def getPossiblePhysicalExtents(floor=0):
-    """Returns a list of integers representing the possible values for
-       the physical extent of a volume group.  Value is in KB.
-
-       floor - size (in KB) of smallest PE we care about.
-    """
-
-    possiblePE = []
-    curpe = 8
-    while curpe <= 16384*1024:
-	if curpe >= floor:
-	    possiblePE.append(curpe)
-	curpe = curpe * 2
-
-    return possiblePE
-
-def getMaxLVSize():
-    """ Return the maximum size (in MB) of a logical volume. """
-    if arch.getArch() in ("x86_64", "ppc64", "alpha", "ia64", "s390", "sparc"): #64bit architectures
-        return (8*1024*1024*1024*1024) #Max is 8EiB (very large number..)
-    else:
-        return (16*1024*1024) #Max is 16TiB
-
-def clampSize(size, pesize, roundup=None):
-    if roundup:
-        round = math.ceil
-    else:
-        round = math.floor
-
-    return long(round(float(size)/float(pesize)) * pesize)
-
-def get_pv_space(size, disks, pesize=LVM_PE_SIZE,
-                 striped=False, mirrored=False):
-    """ 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
-    space = clampSize(size, pesize, roundup=True) + \
-            pesize
-    return space
-
-def lvm(args):
-    ret = util.run_program(["lvm"] + args)
-    if ret:
-        raise LVMError("running lvm " + " ".join(args) + " failed")
-
-def pvcreate(device):
-    # we force dataalignment=1024k since we cannot get lvm to tell us what
-    # the pe_start will be in advance
-    args = ["pvcreate"] + \
-            config_args + \
-            ["--dataalignment", "1024k"] + \
-            [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)] + \
-            config_args + \
-            [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"] + \
-            config_args + \
-            [device]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("pvremove failed for %s: %s" % (device, msg))
-
-def pvinfo(device):
-    """
-        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/.*/"] }'
-    """
-    #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'" 
-    args = ["pvs", "--noheadings"] + \
-            ["--units", "m"] + \
-            ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \
-            config_args + \
-            [device]
-
-    rc = util.capture_output(["lvm"] + args)
-    vals = rc.split()
-    if not vals:
-        raise LVMError("pvinfo failed for %s" % device)
-
-    # don't raise an exception if pv is not a part of any vg
-    pv_name = vals[0]
-    try:
-        vg_name, vg_uuid = vals[2], vals[3]
-    except IndexError:
-        vg_name, vg_uuid = "", ""
-    
-    info = {'pv_name': pv_name,
-            'vg_name': vg_name,
-            'vg_uuid': vg_uuid}
-
-    return info
-
-def vgcreate(vg_name, pv_list, pe_size):
-    argv = ["vgcreate"]
-    if pe_size:
-        argv.extend(["-s", "%dm" % pe_size])
-    argv.extend(config_args)
-    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"] + \
-            config_args +\
-            [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"] + \
-            config_args + \
-            [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"] + \
-            config_args + \
-            [vg_name]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("vgdeactivate failed for %s: %s" % (vg_name, msg))
-
-def vgreduce(vg_name, pv_list, rm=False):
-    """ Reduce a VG.
-
-    rm -> with RemoveMissing option.
-    Use pv_list when rm=False, otherwise ignore pv_list and call vgreduce with
-    the --removemissing option.
-    """
-    args = ["vgreduce"]
-    args.extend(config_args)
-    if rm:
-        args.extend(["--removemissing", "--force", vg_name])
-    else:
-        args.extend([vg_name] + pv_list)
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("vgreduce failed for %s: %s" % (vg_name, msg))
-
-def vginfo(vg_name):
-    args = ["vgs", "--noheadings", "--nosuffix"] + \
-            ["--units", "m"] + \
-            ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \
-            config_args + \
-            [vg_name]
-
-    buf = util.capture_output(["lvm"] + args)
-    info = buf.split()
-    if len(info) != 7:
-        raise LVMError(_("vginfo failed for %s" % vg_name))
-
-    d = {}
-    (d['uuid'],d['size'],d['free'],d['pe_size'],
-     d['pe_count'],d['pe_free'],d['pv_count']) = info
-    return d
-
-def lvs(vg_name):
-    args = ["lvs", "--noheadings", "--nosuffix"] + \
-            ["--units", "m"] + \
-            ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
-            config_args + \
-            [vg_name]
-
-    buf = util.capture_output(["lvm"] + args)
-
-    lvs = {}
-    for line in buf.splitlines():
-        line = line.strip()
-        if not line:
-            continue
-        (name, uuid, size, attr) = line.split()
-        lvs[name] = {"size": size,
-                     "uuid": uuid,
-                     "attr": attr}
-
-    if not lvs:
-        raise LVMError(_("lvs failed for %s" % vg_name))
-
-    return lvs
-
-def lvorigin(vg_name, lv_name):
-    args = ["lvs", "--noheadings", "-o", "origin"] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    buf = util.capture_output(["lvm"] + args)
-
-    try:
-        origin = buf.splitlines()[0].strip()
-    except IndexError:
-        origin = ''
-
-    return origin
-
-def lvcreate(vg_name, lv_name, size, pvs=[]):
-    args = ["lvcreate"] + \
-            ["-L", "%dm" % size] + \
-            ["-n", lv_name] + \
-            config_args + \
-            [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):
-    args = ["lvremove"] + \
-            config_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] + \
-            config_args + \
-            ["%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):
-    # see if lvchange accepts paths of the form 'mapper/$vg-$lv'
-    args = ["lvchange", "-a", "y"] + \
-            config_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"] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("lvdeactivate failed for %s: %s" % (lv_name, msg))
-
diff --git a/pyanaconda/storage/devicelibs/mdraid.py b/pyanaconda/storage/devicelibs/mdraid.py
deleted file mode 100644
index ab18641..0000000
--- a/pyanaconda/storage/devicelibs/mdraid.py
+++ /dev/null
@@ -1,280 +0,0 @@
-#
-# mdraid.py
-# mdraid functions
-#
-# Copyright (C) 2009  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-
-from .. import util
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-# these defaults were determined empirically
-MD_SUPERBLOCK_SIZE = 2.0    # MB
-MD_CHUNK_SIZE = 0.5         # MB
-
-# raidlevels constants
-RAID10 = 10
-RAID6 = 6
-RAID5 = 5
-RAID4 = 4
-RAID1 = 1
-RAID0 = 0
-
-def getRaidLevels():
-    mdstat_descriptors = {
-        RAID10: ("[RAID10]", "[raid10]"),
-        RAID6: ("[RAID6]", "[raid6]"),
-        RAID5: ("[RAID5]", "[raid5]"),
-        RAID4: ("[RAID4]", "[raid4]"),
-        RAID1: ("[RAID1]", "[raid1]"),
-        RAID0: ("[RAID0]", "[raid0]"),
-    }
-    avail = []
-    try:
-        f = open("/proc/mdstat", "r")
-    except IOError:
-        pass
-    else:
-        for l in f.readlines():
-            if not l.startswith("Personalities"):
-                continue
-
-            lst = l.split()
-
-            for level in mdstat_descriptors:
-                for d in mdstat_descriptors[level]:
-                    if d in lst:
-                        avail.append(level)
-                        break
-
-        f.close()
-
-    avail.sort()
-    return avail
-
-raid_levels = getRaidLevels()
-
-raid_descriptors = {RAID10: ("raid10", "RAID10", "10", 10),
-                    RAID6: ("raid6", "RAID6", "6", 6),
-                    RAID5: ("raid5", "RAID5", "5", 5),
-                    RAID4: ("raid4", "RAID4", "4", 4),
-                    RAID1: ("raid1", "mirror", "RAID1", "1", 1),
-                    RAID0: ("raid0", "stripe", "RAID0", "0", 0)}
-
-def raidLevel(descriptor):
-    for level in raid_levels:
-        if isRaid(level, descriptor):
-            return level
-    else:
-        raise MDRaidError("invalid raid level descriptor %s" % descriptor)
-
-def raidLevelString(level):
-    if level in raid_descriptors.keys():
-        return raid_descriptors[level][0]
-    else:
-        raise MDRaidError("invalid raid level constant %s" % level)
-
-def isRaid(raid, raidlevel):
-    """Return whether raidlevel is a valid descriptor of raid"""
-    if raid in raid_descriptors:
-        return raidlevel in raid_descriptors[raid]
-    else:
-        raise MDRaidError("invalid raid level %d" % raid)
-
-def get_raid_min_members(raidlevel):
-    """Return the minimum number of raid members required for raid level"""
-    raid_min_members = {RAID10: 2,
-                        RAID6: 4,
-                        RAID5: 3,
-                        RAID4: 3,
-                        RAID1: 2,
-                        RAID0: 2}
-
-    for raid, min_members in raid_min_members.items():
-        if isRaid(raid, raidlevel):
-            return min_members
-
-    raise MDRaidError("invalid raid level %d" % raidlevel)
-
-def get_raid_max_spares(raidlevel, nummembers):
-    """Return the maximum number of raid spares for raidlevel."""
-    raid_max_spares = {RAID10: lambda: max(0, nummembers - get_raid_min_members(RAID10)),
-                       RAID6: lambda: max(0, nummembers - get_raid_min_members(RAID6)),
-                       RAID5: lambda: max(0, nummembers - get_raid_min_members(RAID5)),
-                       RAID4: lambda: max(0, nummembers - get_raid_min_members(RAID4)),
-                       RAID1: lambda: max(0, nummembers - get_raid_min_members(RAID1)),
-                       RAID0: lambda: 0}
-
-    for raid, max_spares_func in raid_max_spares.items():
-        if isRaid(raid, raidlevel):
-            return max_spares_func()
-
-    raise MDRaidError("invalid raid level %d" % raidlevel)
-
-def get_member_space(size, disks, level=None):
-    space = 0   # size of *each* member device
-
-    if isinstance(level, str):
-        level = raidLevel(level)
-
-    min_members = get_raid_min_members(level)
-    if disks < min_members:
-        raise MDRaidError("raid%d requires at least %d disks"
-                         % (level, min_members))
-
-    if level == RAID0:
-        # you need the sum of the member sizes to equal your desired capacity
-        space = size / disks
-    elif level == RAID1:
-        # you need each member's size to equal your desired capacity
-        space = size
-    elif level in (RAID4, RAID5):
-        # you need the sum of all but one members' sizes to equal your desired
-        # capacity
-        space = size / (disks - 1)
-    elif level == RAID6:
-        # you need the sum of all but two members' sizes to equal your desired
-        # capacity
-        space = size / (disks - 2)
-    elif level == RAID10:
-        # you need the sum of the member sizes to equal twice your desired
-        # capacity
-        space = size / (disks / 2.0)
-
-    space += MD_SUPERBLOCK_SIZE
-
-    return space * disks
-
-def mdadm(args):
-    ret = util.run_program(["mdadm"] + args)
-    if ret:
-        raise MDRaidError("running mdadm " + " ".join(args) + " failed")
-
-def mdcreate(device, level, disks, spares=0, metadataVer=None, bitmap=False):
-    argv = ["--create", device, "--run", "--level=%s" % level]
-    raid_devs = len(disks) - spares
-    argv.append("--raid-devices=%d" % raid_devs)
-    if spares:
-        argv.append("--spare-devices=%d" % spares)
-    if metadataVer:
-        argv.append("--metadata=%s" % metadataVer)
-    if bitmap:
-        argv.append("--bitmap=internal")
-    argv.extend(disks)
-    
-    try:
-        mdadm(argv)
-    except MDRaidError as msg:
-        raise MDRaidError("mdcreate failed for %s: %s" % (device, msg))
-
-def mddestroy(device):
-    args = ["--zero-superblock", device]
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mddestroy failed for %s: %s" % (device, msg))
-
-def mdadd(device):
-    args = ["--incremental", "--quiet"]
-    args.append(device)
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mdadd failed for %s: %s" % (device, msg))
-
-def mdactivate(device, members=[], super_minor=None, uuid=None):
-    if super_minor is None and not uuid:
-        raise MDRaidError("mdactivate requires either a uuid or a super-minor")
-    
-    if uuid:
-        identifier = "--uuid=%s" % uuid
-    else:
-        identifier = ""
-
-    args = ["--assemble", device, identifier, "--run"]
-    args += members
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mdactivate failed for %s: %s" % (device, msg))
-
-def mddeactivate(device):
-    args = ["--stop", device]
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mddeactivate failed for %s: %s" % (device, msg))
-
-def mdexamine(device):
-    _vars = util.capture_output(["mdadm",
-                                 "--examine", "--brief", device]).split()
-
-    info = {}
-    if len(_vars) > 1 and _vars[1].startswith("/dev/md"):
-        info["device"] = _vars[1]
-        _vars = _vars[2:]
-    elif len(_vars) > 1:
-        _vars = _vars[1:]
-
-    for var in _vars:
-        (name, equals, value) = var.partition("=")
-        if not equals:
-            continue
-
-        info[name.lower()] = value.strip()
-
-    return info
-
-def md_node_from_name(name):
-    named_path = "/dev/md/" + name
-    try:
-        node = os.path.basename(os.readlink(named_path))
-    except OSError as e:
-        raise MDRaidError("md_node_from_name failed: %s" % e)
-    else:
-        return node
-
-def name_from_md_node(node):
-    md_dir = "/dev/md"
-    name = None
-    # It's sad, but it's what we've got.
-    for link in os.listdir(md_dir):
-        full_path = "%s/%s" % (md_dir, link)
-        md_name = os.path.basename(os.readlink(full_path))
-        log.debug("link: %s -> %s" % (link, os.readlink(full_path)))
-        if md_name == node:
-            name = link
-            break
-
-    if not name:
-        raise MDRaidError("name_from_md_node(%s) failed" % node)
-
-    log.debug("returning %s" % name)
-    return name
diff --git a/pyanaconda/storage/devicelibs/mpath.py b/pyanaconda/storage/devicelibs/mpath.py
deleted file mode 100644
index d49ab07..0000000
--- a/pyanaconda/storage/devicelibs/mpath.py
+++ /dev/null
@@ -1,285 +0,0 @@
-
-import re
-
-from ..udev import udev_device_is_disk
-from .. import util
-from ..flags import flags
-from ..storage_log import log_method_call
-
-import logging
-log = logging.getLogger("storage")
-
-def parseMultipathOutput(output):
-    """
-    Parse output from "multipath -d" or "multipath -ll" and form a topology.
-
-    Returns a dictionary:
-    {'mpatha':['sdb','sdc'], 'mpathb': ['sdd', 'sde'], ... }
-
-    The 'multipath -d' output looks like:
-    create: mpathc (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
-    size=112G features='0' hwhandler='0' wp=undef
-    `-+- policy='round-robin 0' prio=1 status=undef
-    `- 2:0:0:0 sda 8:0  undef ready running
-    create: mpathb (36006016092d21800703762872c60db11) undef DGC,RAID 5
-    size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
-    `-+- policy='round-robin 0' prio=2 status=undef
-    |- 6:0:0:0 sdb 8:16 undef ready running
-    `- 7:0:0:0 sdc 8:32 undef ready running
-    create: mpatha (36001438005deb4710000500000270000) dm-0 HP,HSV400
-    size=20G features='0' hwhandler='0' wp=rw
-    |-+- policy='round-robin 0' prio=-1 status=active
-    | |- 7:0:0:1 sda 8:0  active undef running
-    | `- 7:0:1:1 sdb 8:16 active undef running
-    `-+- policy='round-robin 0' prio=-1 status=enabled
-    |- 7:0:2:1 sdc 8:32 active undef running
-    `- 7:0:3:1 sdd 8:48 active undef running
-
-    (In anaconda, the first one there won't be included because we blacklist
-    "ATA" as a vendor.)
-
-    The 'multipath -ll' output looks like (notice the missing 'create' before
-    'mpatha'):
-
-    mpatha (3600a0b800067fcc9000001694b557dd1) dm-0 IBM,1726-4xx  FAStT
-    size=360G features='0' hwhandler='1 rdac' wp=rw
-    `-+- policy='round-robin 0' prio=3 status=active
-      |- 2:0:0:0 sda 8:0  active ready running
-      `- 3:0:0:0 sdb 8:16 active ready running
-
-    """
-    mpaths = {}
-    if output is None:
-        return mpaths
-
-    name = None
-    devices = []
-
-    policy = re.compile('^[|+` -]+policy')
-    device = re.compile('^[|+` -]+[0-9]+:[0-9]+:[0-9]+:[0-9]+ ([a-zA-Z0-9!/]+)')
-    create = re.compile('^(create: )?(mpath\w+|[a-f0-9]+)')
-
-    lines = output.split('\n')
-    for line in lines:
-        pmatch = policy.match(line)
-        dmatch = device.match(line)
-        cmatch = create.match(line)
-        lexemes = line.split()
-        if not lexemes:
-            break
-        if cmatch and cmatch.group(2):
-            if name and devices:
-                mpaths[name] = devices
-                name = None
-                devices = []
-            name = cmatch.group(2)
-        elif lexemes[0].startswith('size='):
-            pass
-        elif pmatch:
-            pass
-        elif dmatch:
-            devices.append(dmatch.groups()[0].replace('!','/'))
-
-    if name and devices:
-        mpaths[name] = devices
-
-    return mpaths
-
-class MultipathTopology(object):
-    def __init__(self, devices_list):
-        self._devices = devices_list
-        self._nondisks = []
-        self._singlepaths = []
-        self._multipaths = [] # mpath members
-        self._devmap = {}
-
-        self._build_topology()
-
-    def _build_devmap(self):
-        self._devmap = {}
-        for dev in self._devices:
-            self._devmap[dev['name']] = dev
-
-    def _build_mpath_topology(self):
-        with open("/etc/multipath.conf") as conf:
-            log.debug("/etc/multipath.conf contents:")
-            map(lambda line: log.debug(line.rstrip()), conf)
-            log.debug("(end of /etc/multipath.conf)")
-        self._mpath_topology = parseMultipathOutput(
-            util.capture_output(["multipath", "-d"]))
-        self._mpath_topology.update(parseMultipathOutput(
-            util.capture_output(["multipath", "-ll"])))
-
-        delete_keys = []
-        for (mp, disks) in self._mpath_topology.items():
-            # single device mpath is not really an mpath, eliminate them:
-            if len(disks) < 2:
-                log.info("MultipathTopology: not a multipath: %s" % disks)
-                delete_keys.append(mp)
-                continue
-            # some usb cardreaders use multiple lun's (for different slots) and
-            # report a fake disk serial which is the same for all the lun's
-            # (#517603). find those mpaths and eliminate them:
-            only_non_usbs = [d for d in disks if
-                             self._devmap[d].get("ID_USB_DRIVER") != "usb-storage"]
-            if len(only_non_usbs) == 0:
-                log.info("DeviceToppology: found multi lun usb "
-                         "mass storage device: %s" % disks)
-                delete_keys.append(mp)
-        map(lambda key: self._mpath_topology.pop(key), delete_keys)
-
-    def _build_topology(self):
-        log_method_call(self)
-        self._build_devmap()
-        self._build_mpath_topology()
-
-        for dev in self._devices:
-            name = dev['name']
-            if not udev_device_is_disk(dev):
-                self._nondisks.append(name)
-                log.info("MultipathTopology: found non-disk device: %s" % name)
-                continue
-            mpath_name = self.multipath_name(name)
-            if mpath_name:
-                dev["ID_FS_TYPE"] = "multipath_member"
-                dev["ID_MPATH_NAME"] = mpath_name
-                log.info("MultipathTopology: found a multipath member of %s: %s " %
-                         (mpath_name, name))
-                continue
-            # it's a disk and not a multipath member (can be a coalesced
-            # multipath)
-            self._singlepaths.append(name)
-            log.info("MultipathTopology: found singlepath device: %s" % name)
-
-    def devices_iter(self):
-        """ Generator. Yields all disk devices, mpaths members, coalesced mpath
-            devices and partitions.
-
-            This property guarantees the order of the returned devices is the
-            same as in the device list passed to the object's constructor.
-        """
-        for device in self._devices:
-            yield device
-
-    def singlepaths_iter(self):
-        """ Generator. Yields only the singlepath disks.
-        """
-        for name in self._singlepaths:
-            yield self._devmap[name]
-
-    def multipath_name(self, mpath_member_name):
-        """ If the mpath_member_name is a member of a multipath device return
-            the name of the device (e.g. mpathc).
-
-            Else return None.
-        """
-        for (name, members) in self._mpath_topology.items():
-            if mpath_member_name in members:
-                return name
-        return None
-
-    def multipaths_iter(self):
-        """Generator. Yields all the multipath members, in a topology.
-
-           Every iteration returns a list of mpath member devices forming a
-           multipath.
-        """
-        for disks in self._mpath_topology.values():
-            yield [self._devmap[d] for d in disks]
-
-
-class MultipathConfigWriter:
-    def __init__(self):
-        self.blacklist_devices = []
-        self.mpaths = []
-
-    def addBlacklistDevice(self, device):
-        self.blacklist_devices.append(device)
-
-    def addMultipathDevice(self, mpath):
-        self.mpaths.append(mpath)
-
-    def write(self, friendly_names):
-        # if you add anything here, be sure and also add it to anaconda's
-        # multipath.conf
-        ret = ''
-        ret += """\
-# multipath.conf written by anaconda
-
-defaults {
-	user_friendly_names %(friendly_names)s
-}
-blacklist {
-	devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
-	devnode "^hd[a-z]"
-	devnode "^dcssblk[0-9]*"
-	device {
-		vendor "DGC"
-		product "LUNZ"
-	}
-	device {
-		vendor "IBM"
-		product "S/390.*"
-	}
-	# don't count normal SATA devices as multipaths
-	device {
-		vendor  "ATA"
-	}
-	# don't count 3ware devices as multipaths
-	device {
-		vendor  "3ware"
-	}
-	device {
-		vendor  "AMCC"
-	}
-	# nor highpoint devices
-	device {
-		vendor  "HPT"
-	}
-""" % {'friendly_names' : "yes" if friendly_names else "no"}
-        for device in self.blacklist_devices:
-            if device.serial:
-                ret += '\twwid "%s"\n' % device.serial
-            elif device.vendor and device.model:
-                ret += '\tdevice {\n'
-                ret += '\t\tvendor %s\n' % device.vendor
-                ret += '\t\tproduct %s\n' % device.model
-                ret += '\t}\n'
-        if self.mpaths:
-                ret += '\twwid "*"\n'
-                ret += '}\n'
-                ret += 'blacklist_exceptions {\n'
-                for mpath in self.mpaths:
-                    for k,v in mpath.config.items():
-                        if k == 'wwid':
-                            ret += '\twwid "%s"\n' % v
-        ret += '}\n'
-        ret += 'multipaths {\n'
-        for mpath in self.mpaths:
-            ret += '\tmultipath {\n'
-            for k,v in mpath.config.items():
-                if k == 'wwid':
-                    ret += '\t\twwid "%s"\n' % v
-                else:
-                    ret += '\t\t%s %s\n' % (k, v)
-            ret += '\t}\n'
-        ret += '}\n'
-
-        return ret
-
-    def writeConfig(self, friendly_names=True):
-        if not flags.multipath:
-            # not writing out a multipath.conf will effectively blacklist all
-            # mpath which will prevent any of them from being activated during
-            # install
-            return
-
-        cfg = self.write(friendly_names)
-        with open("/etc/multipath.conf", "w+") as mpath_cfg:
-            mpath_cfg.write(cfg)
-
-def flush_mpaths():
-    util.run_program(["multipath", "-F"])
-    check_output = util.capture_output(["multipath", "-ll"]).strip()
-    if check_output:
-        log.error("multipath: some devices could not be flushed")
diff --git a/pyanaconda/storage/devicelibs/swap.py b/pyanaconda/storage/devicelibs/swap.py
deleted file mode 100644
index 4c9490a..0000000
--- a/pyanaconda/storage/devicelibs/swap.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# swap.py
-# Python module for managing swap devices.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import resource
-import os
-
-from ..errors import *
-from .. import util
-from . import dm
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def mkswap(device, label=''):
-    # We use -f to force since mkswap tends to refuse creation on lvs with
-    # a message about erasing bootbits sectors on whole disks. Bah.
-    argv = ["-f"]
-    if label:
-        argv.extend(["-L", label])
-    argv.append(device)
-
-    ret = util.run_program(["mkswap"] + argv)
-
-    if ret:
-        raise SwapError("mkswap failed for '%s'" % device)
-
-def swapon(device, priority=None):
-    pagesize = resource.getpagesize()
-    buf = None
-    sig = None
-
-    if pagesize > 2048:
-        num = pagesize
-    else:
-        num = 2048
-
-    try:
-        fd = os.open(device, os.O_RDONLY)
-        buf = os.read(fd, num)
-    except OSError:
-        pass
-    finally:
-        try:
-            os.close(fd)
-        except (OSError, UnboundLocalError):
-            pass
-
-    if buf is not None and len(buf) == pagesize:
-        sig = buf[pagesize - 10:]
-        if sig == 'SWAP-SPACE':
-            raise OldSwapError
-        if sig == 'S1SUSPEND\x00' or sig == 'S2SUSPEND\x00':
-            raise SuspendError
-
-    if sig != 'SWAPSPACE2':
-        raise UnknownSwapError
-
-    argv = []
-    if isinstance(priority, int) and 0 <= priority <= 32767:
-        argv.extend(["-p", "%d" % priority])
-    argv.append(device)
-        
-    rc = util.run_program(["swapon"] + argv)
-
-    if rc:
-        raise SwapError("swapon failed for '%s'" % device)
-
-def swapoff(device):
-    rc = util.run_program(["swapoff", device])
-
-    if rc:
-        raise SwapError("swapoff failed for '%s'" % device)
-
-def swapstatus(device):
-    alt_dev = None
-    if device.startswith("/dev/mapper/"):
-        # get the real device node for device-mapper devices since the ones
-        # with meaningful names are just symlinks
-        try:
-            alt_dev = "/dev/%s" % dm.dm_node_from_name(device.split("/")[-1])
-        except DMError:
-            alt_dev = None
-
-    lines = open("/proc/swaps").readlines()
-    status = False
-    for line in lines:
-        if not line.strip():
-            continue
-
-        swap_dev = line.split()[0]
-        if swap_dev in [device, alt_dev]:
-            status = True
-            break
-
-    return status
-
-def swapSuggestion(quiet=False, hibernation=False):
-    """
-    Suggest the size of the swap partition that will be created.
-
-    @param quiet: log size information
-    @param hibernation: calculate swap size big enough for hibernation
-    @return: calculated swap size
-
-    """
-
-    mem = util.total_memory()/1024
-    mem = ((mem/16)+1)*16
-    if not quiet:
-        log.info("Detected %sM of memory", mem)
-
-    #chart suggested in the discussion with other teams
-    if mem < 2048:
-        swap = 2 * mem
-
-    elif 2048 <= mem < 8192:
-        swap = mem
-
-    elif 8192 <= mem < 65536:
-        swap = mem / 2
-
-    else:
-        swap = 4096
-
-    if hibernation:
-        if mem <= 65536:
-            swap = mem + swap
-        else:
-            log.info("Ignoring --hibernation option on systems with 64 GB of RAM or more")
-
-    if not quiet:
-        log.info("Swap attempt of %sM", swap)
-
-    return swap
-
diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py
deleted file mode 100644
index 1a4b4d0..0000000
--- a/pyanaconda/storage/devices.py
+++ /dev/null
@@ -1,4190 +0,0 @@
-# devices.py
-# Device classes for anaconda's storage configuration module.
-# 
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-
-"""
-    Device classes for use by anaconda.
-
-    This is the hierarchy of device objects that anaconda will use for
-    managing storage devices in the system. These classes will
-    individually make use of external support modules as needed to
-    perform operations specific to the type of device they represent.
-
-    TODO:
-        - see how to do network devices (NetworkManager may help)
-          - perhaps just a wrapper here
-        - document return values of all methods/functions
-        - find out what other kinds of wild and crazy devices we need to
-          represent here (iseries? xen? more mainframe? mac? ps?)
-            - PReP
-              - this is a prime candidate for a PseudoDevice
-            - DASD
-            - ZFCP
-            - XEN
-
-    What specifications do we allow?              new        existing
-        partitions                              
-            usage                                  +            +
-                filesystem, partition type are implicit
-            mountpoint                             +            +
-            size
-                exact                              +            -
-                range                              +            -
-                resize                             -            +
-            format                                 -            +
-            encryption                             +            +
-
-            disk                                                 
-                exact                              +            -
-                set                                +            -
-                    how will we specify this?
-                        partition w/ multiple parents cannot otherwise occur
-            primary                                +            -
-
-        mdraid sets
-            filesystem (*)                         +            +
-            mountpoint                             +            +
-            size?                                                
-            format                                 -            +
-            encryption                             +            +
-
-            level                                  +            ? 
-            device minor                           +            ? 
-            member devices                         +            ? 
-            spares                                 +            ? 
-            name?
-            bitmap? (boolean)                      +            -
-
-        volume groups
-            name                                   +            - 
-            member pvs                             +            +
-            pesize                                 +            ?
-
-        logical volumes
-            filesystem                             +            +
-            mountpoint                             +            +
-            size
-                exact                              +            ?
-            format                                 -            +
-            encryption                             +            +
-
-            name                                   +            ?
-            vgname                                 +            ?
-
-
-"""
-
-import os
-import math
-import copy
-import pprint
-import tempfile
-
-# device backend modules
-from devicelibs import mdraid
-from devicelibs import lvm
-from devicelibs import dm
-from devicelibs import loop
-from devicelibs import btrfs
-from devicelibs import crypto
-import parted
-import _ped
-import block
-
-from errors import *
-import util
-import arch
-from flags import flags
-from storage_log import log_method_call
-from udev import *
-from formats import get_device_format_class, getFormat, DeviceFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import logging
-log = logging.getLogger("storage")
-
-def get_device_majors():
-    majors = {}
-    for line in open("/proc/devices").readlines():
-        try:
-            (major, device) = line.split()
-        except ValueError:
-            continue
-        try:
-            majors[int(major)] = device
-        except ValueError:
-            continue
-    return majors
-device_majors = get_device_majors()
-
-
-def devicePathToName(devicePath):
-    if devicePath.startswith("/dev/"):
-        name = devicePath[5:]
-    else:
-        name = devicePath
-
-    if name.startswith("mapper/"):
-        name = name[7:]
-
-    if name.startswith("md/"):
-        name = name[3:]
-
-    return name
-
-
-def deviceNameToDiskByPath(deviceName=None):
-    if not deviceName:
-        return ""
-
-    ret = None
-    for dev in udev_get_block_devices():
-        if udev_device_get_name(dev) == deviceName:
-            ret = udev_device_get_by_path(dev)
-            break
-
-    if ret:
-        return ret
-    raise DeviceNotFoundError(deviceName)
-
-class Device(object):
-    """ A generic device.
-
-        Device instances know which devices they depend upon (parents
-        attribute). They do not know which devices depend upon them, but
-        they do know whether or not they have any dependent devices
-        (isleaf attribute).
-
-        A Device's setup method should set up all parent devices as well
-        as the device itself. It should not run the resident format's
-        setup method.
-
-            Which Device types rely on their parents' formats being active?
-                DMCryptDevice
-
-        A Device's teardown method should accept the keyword argument
-        recursive, which takes a boolean value and indicates whether or
-        not to recursively close parent devices.
-
-        A Device's create method should create all parent devices as well
-        as the device itself. It should also run the Device's setup method
-        after creating the device. The create method should not create a
-        device's resident format.
-
-            Which device type rely on their parents' formats to be created
-            before they can be created/assembled?
-                VolumeGroup
-                DMCryptDevice
-
-        A Device's destroy method should destroy any resident format
-        before destroying the device itself.
-
-    """
-
-    # This is a counter for generating unique ids for Devices.
-    _id = 0
-
-    _type = "device"
-    _packages = []
-    _services = []
-
-    def __init__(self, name, parents=None):
-        """ Create a Device instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                parents -- a list of required Device instances
-
-        """
-        self._name = name
-        if parents is None:
-            parents = []
-        elif not isinstance(parents, list):
-            raise ValueError("parents must be a list of Device instances")
-        self.parents = parents
-        self.kids = 0
-
-        # Set this instance's id and increment the counter.
-        self.id = Device._id
-        Device._id += 1
-
-        for parent in self.parents:
-            parent.addChild()
-
-    def __deepcopy__(self, memo):
-        """ Create a deep copy of a Device instance.
-
-            We can't do copy.deepcopy on parted objects, which is okay.
-            For these parted objects, we just do a shallow copy.
-        """
-        new = self.__class__.__new__(self.__class__)
-        memo[id(self)] = new
-        dont_copy_attrs = ('_raidSet',)
-        shallow_copy_attrs = ('_partedDevice', '_partedPartition')
-        for (attr, value) in self.__dict__.items():
-            if attr in dont_copy_attrs:
-                setattr(new, attr, value)
-            elif attr in shallow_copy_attrs:
-                setattr(new, attr, copy.copy(value))
-            else:
-                setattr(new, attr, copy.deepcopy(value, memo))
-
-        return new
-
-    def __repr__(self):
-        s = ("%(type)s instance (%(id)s) --\n"
-             "  name = %(name)s  status = %(status)s"
-             "  kids = %(kids)s id = %(dev_id)s\n"
-             "  parents = %(parents)s\n" %
-             {"type": self.__class__.__name__, "id": "%#x" % id(self),
-              "name": self.name, "kids": self.kids, "status": self.status,
-              "dev_id": self.id,
-              "parents": pprint.pformat([str(p) for p in self.parents])})
-        return s
-
-    def __str__(self):
-        s = "%s %s (%d)" % (self.type, self.name, self.id)
-        return s
-
-    @property
-    def dict(self):
-        d =  {"type": self.type, "name": self.name,
-              "parents": [p.name for p in self.parents]}
-        return d
-
-    def removeChild(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        self.kids -= 1
-
-    def addChild(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        self.kids += 1
-
-    def setup(self):
-        """ Open, or set up, a device. """
-        raise NotImplementedError("setup method not defined for Device")
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        raise NotImplementedError("teardown method not defined for Device")
-
-    def create(self):
-        """ Create the device. """
-        raise NotImplementedError("create method not defined for Device")
-
-    def destroy(self):
-        """ Destroy the device. """
-        raise NotImplementedError("destroy method not defined for Device")
-
-    def setupParents(self, orig=False):
-        """ Run setup method of all parent devices. """
-        log_method_call(self, name=self.name, orig=orig, kids=self.kids)
-        for parent in self.parents:
-            parent.setup(orig=orig)
-
-    def teardownParents(self, recursive=None):
-        """ Run teardown method of all parent devices. """
-        for parent in self.parents:
-            parent.teardown(recursive=recursive)
-
-    def dependsOn(self, dep):
-        """ Return True if this device depends on dep. """
-        # XXX does a device depend on itself?
-        if dep in self.parents:
-            return True
-
-        for parent in self.parents:
-            if parent.dependsOn(dep):
-                return True
-
-        return False
-
-    def dracutSetupArgs(self):
-        return set()
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        return False
-
-    @property
-    def name(self):
-        """ This device's name. """
-        return self._name
-
-    @property
-    def isleaf(self):
-        """ True if this device has no children. """
-        return self.kids == 0
-
-    @property
-    def typeDescription(self):
-        """ String describing the device type. """
-        return self._type
-
-    @property
-    def type(self):
-        """ Device type. """
-        return self._type
-
-    @property
-    def ancestors(self):
-        l = set([self])
-        for p in [d for d in self.parents if d not in l]:
-            l.update(set(p.ancestors))
-        return list(l)
-
-    @property
-    def packages(self):
-        """ List of packages required to manage devices of this type.
-
-            This list includes the packages required by its parent devices.
-        """
-        packages = self._packages
-        for parent in self.parents:
-            for package in parent.packages:
-                if package not in packages:
-                    packages.append(package)
-
-        return packages
-
-    @property
-    def services(self):
-        """ List of services required to manage devices of this type.
-
-            This list includes the services required by its parent devices."
-        """
-        services = self._services
-        for parent in self.parents:
-            for service in parent.services:
-                if service not in services:
-                    services.append(service)
-
-        return services
-
-    @property
-    def mediaPresent(self):
-        return True
-
-
-class NetworkStorageDevice(object):
-    """ Virtual base class for network backed storage devices """
-
-    def __init__(self, host_address=None, nic=None):
-        """ Create a NetworkStorage Device instance. Note this class is only
-            to be used as a baseclass and then only with multiple inheritance.
-            The only correct use is:
-            class MyStorageDevice(StorageDevice, NetworkStorageDevice):
-
-            The sole purpose of this class is to:
-            1) Be able to check if a StorageDevice is network backed
-               (using isinstance).
-            2) To be able to get the host address of the host (server) backing
-               the storage *or* the NIC through which the storage is connected
-
-            Arguments:
-
-                host_address -- host address of the backing server
-                nic -- nic to which the storage is bound
-        """
-        self.host_address = host_address
-        self.nic = nic
-
-
-class StorageDevice(Device):
-    """ A generic storage device.
-
-        A fully qualified path to the device node can be obtained via the
-        path attribute, although it is not guaranteed to be useful, or
-        even present, unless the StorageDevice's setup method has been
-        run.
-
-        StorageDevice instances can optionally contain a filesystem,
-        represented by an FS instance. A StorageDevice's create method
-        should create a filesystem if one has been specified.
-    """
-    _type = "storage"
-    _devDir = "/dev"
-    sysfsBlockDir = "class/block"
-    _resizable = False
-    _partitionable = False
-    _isDisk = False
-
-    def __init__(self, name, format=None, uuid=None,
-                 size=None, major=None, minor=None,
-                 sysfsPath='', parents=None, exists=False, serial=None,
-                 vendor="", model="", bus=""):
-        """ Create a StorageDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                major -- the device major
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                uuid -- universally unique identifier
-                parents -- a list of required Device instances
-                serial -- the ID_SERIAL_SHORT for this device
-                vendor -- the manufacturer of this Device
-                model -- manufacturer's device model string
-                bus -- the interconnect this device uses
-
-        """
-        # allow specification of individual parents
-        if isinstance(parents, Device):
-            parents = [parents]
-
-        self.exists = exists
-        Device.__init__(self, name, parents=parents)
-
-        self.uuid = uuid
-        self._format = None
-        self._size = util.numeric_type(size)
-        self.major = util.numeric_type(major)
-        self.minor = util.numeric_type(minor)
-        self.sysfsPath = sysfsPath
-        self._serial = serial
-        self._vendor = vendor
-        self._model = model
-        self.bus = bus
-
-        self.protected = False
-        self.controllable = not flags.testing
-
-        self.format = format
-        self.originalFormat = copy.copy(self.format)
-        self.fstabComment = ""
-        self._targetSize = self._size
-
-        self._partedDevice = None
-
-        if self.exists and flags.testing and not self._size:
-            def read_int_from_sys(path):
-                return int(open(path).readline().strip())
-
-            device_root = "/sys/class/block/%s" % self.name
-            if os.path.exists("%s/queue" % device_root):
-                sector_size = read_int_from_sys("%s/queue/logical_block_size"
-                                                % device_root)
-                size = read_int_from_sys("%s/size" % device_root)
-                self._size = (size * sector_size) / (1024.0 * 1024.0)
-
-    def __str__(self):
-        exist = "existing"
-        if not self.exists:
-            exist = "non-existent"
-        s = "%s %dMB %s" % (exist, self.size, super(StorageDevice, self).__str__())
-        if self.format.type:
-            s += " with %s" % self.format
-
-        return s
-
-    @property
-    def packages(self):
-        """ List of packages required to manage devices of this type.
-
-            This list includes the packages required by this device's
-            format type as well those required by all of its parent 
-            devices.
-        """
-        packages = super(StorageDevice, self).packages
-        packages.extend(self.format.packages)
-        for parent in self.parents:
-            for package in parent.format.packages:
-                if package not in packages:
-                    packages.append(package)
-
-        return packages
-
-    @property
-    def services(self):
-        """ List of services required to manage devices of this type.
-
-            This list includes the services required by this device's
-            format type as well those required by all of its parent
-            devices.
-        """
-        services = super(StorageDevice, self).services
-        services.extend(self.format.services)
-        for parent in self.parents:
-            for service in parent.format.services:
-                if service not in services:
-                    services.append(service)
-
-        return services
-
-    @property
-    def disks(self):
-        """ A list of all disks this device depends on, including itself. """
-        _disks = []
-        for parent in self.parents:
-            for disk in parent.disks:
-                if disk not in _disks:
-                    _disks.append(disk)
-
-        if self.isDisk and not self.format.hidden:
-            _disks.append(self)
-
-        return _disks
-
-    @property
-    def encrypted(self):
-        """ True if this device, or any it requires, is encrypted. """
-        crypted = False
-        for parent in self.parents:
-            if parent.encrypted:
-                crypted = True
-                break
-
-        if not crypted and isinstance(self, DMCryptDevice):
-            crypted = True
-
-        return crypted
-
-    @property
-    def partedDevice(self):
-        if self.exists and self.status and not self._partedDevice:
-            log.debug("looking up parted Device: %s" % self.path)
-
-            # We aren't guaranteed to be able to get a device.  In
-            # particular, built-in USB flash readers show up as devices but
-            # do not always have any media present, so parted won't be able
-            # to find a device.
-            try:
-                self._partedDevice = parted.Device(path=self.path)
-            except (_ped.IOException, _ped.DeviceException):
-                pass
-
-        return self._partedDevice
-
-    def _getTargetSize(self):
-        return self._targetSize
-
-    def _setTargetSize(self, newsize):
-        self._targetSize = newsize
-
-    targetSize = property(lambda s: s._getTargetSize(),
-                          lambda s, v: s._setTargetSize(v),
-                          doc="Target size of this device")
-
-    def __repr__(self):
-        s = Device.__repr__(self)
-        s += ("  uuid = %(uuid)s  size = %(size)s\n"
-              "  format = %(format)s\n"
-              "  major = %(major)s  minor = %(minor)s  exists = %(exists)s"
-              "  protected = %(protected)s\n"
-              "  sysfs path = %(sysfs)s  partedDevice = %(partedDevice)s\n"
-              "  target size = %(targetSize)s  path = %(path)s\n"
-              "  format args = %(formatArgs)s  originalFormat = %(origFmt)s" %
-              {"uuid": self.uuid, "format": self.format, "size": self.size,
-               "major": self.major, "minor": self.minor, "exists": self.exists,
-               "sysfs": self.sysfsPath, "partedDevice": self.partedDevice,
-               "targetSize": self.targetSize, "path": self.path,
-               "protected": self.protected,
-               "formatArgs": self.formatArgs, "origFmt": self.originalFormat.type})
-        return s
-
-    @property
-    def dict(self):
-        d =  super(StorageDevice, self).dict
-        d.update({"uuid": self.uuid, "size": self.size,
-                  "format": self.format.dict, "removable": self.removable,
-                  "major": self.major, "minor": self.minor,
-                  "exists": self.exists, "sysfs": self.sysfsPath,
-                  "targetSize": self.targetSize, "path": self.path})
-        return d
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.name)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        sysfsName = self.name.replace("/", "!")
-        path = os.path.join("/sys", self.sysfsBlockDir, sysfsName)
-        self.sysfsPath = os.path.realpath(path)[4:]
-        log.debug("%s sysfsPath set to %s" % (self.name, self.sysfsPath))
-
-    @property
-    def formatArgs(self):
-        """ Device-specific arguments to format creation program. """
-        return []
-
-    @property
-    def resizable(self):
-        """ Can this type of device be resized? """
-        return (self._resizable and self.exists and self.format.resizable)
-
-    def notifyKernel(self):
-        """ Send a 'change' uevent to the kernel for this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            log.debug("not sending change uevent for non-existent device")
-            return
-
-        if not self.status:
-            log.debug("not sending change uevent for inactive device")
-            return
-
-        path = os.path.normpath("/sys/%s" % self.sysfsPath)
-        try:
-            util.notify_kernel(path, action="change")
-        except (ValueError, IOError) as e:
-            log.warning("failed to notify kernel of change: %s" % e)
-
-    @property
-    def fstabSpec(self):
-        spec = self.path
-        if self.format and self.format.uuid:
-            spec = "UUID=%s" % self.format.uuid
-        return spec
-
-    def resize(self):
-        """ Resize the device.
-
-            New size should already be set.
-        """
-        raise NotImplementedError("resize method not defined for StorageDevice")
-
-    #
-    # setup
-    #
-    def _preSetup(self, orig=False):
-        """ Preparation and pre-condition checking for device setup.
-
-            Return True if setup should proceed or False if not.
-        """
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status or not self.controllable:
-            return False
-
-        self.setupParents(orig=orig)
-        return True
-
-    def _setup(self, orig=False):
-        """ Perform device-specific setup operations. """
-        pass
-
-    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)
-        if not self._preSetup(orig=orig):
-            return
-
-        self._setup(orig=orig)
-        self._postSetup()
-
-    def _postSetup(self):
-        """ Perform post-setup operations. """
-        udev_settle()
-        # we always probe since the device may not be set up when we want
-        # information about it
-        self._size = self.currentSize
-
-    #
-    # teardown
-    #
-    def _preTeardown(self, recursive=None):
-        """ Preparation and pre-condition checking for device teardown.
-
-            Return True if teardown should proceed or False if not.
-        """
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if not self.status or not self.controllable:
-            return False
-
-        if self.originalFormat.exists:
-            self.originalFormat.teardown()
-        self.format.cacheMajorminor()
-        if self.format.exists:
-            self.format.teardown()
-        udev_settle()
-        return True
-
-    def _teardown(self, recursive=None):
-        """ Perform device-specific teardown operations. """
-        pass
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-        if not self._preTeardown(recursive=recursive):
-            return
-
-        self._teardown(recursive=recursive)
-        self._postTeardown(recursive=recursive)
-
-    def _postTeardown(self, recursive=None):
-        """ Perform post-teardown operations. """
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    #
-    # create
-    #
-    def _preCreate(self):
-        """ Preparation and pre-condition checking for device creation. """
-        if self.exists:
-            raise DeviceError("device has already been created", self.name)
-
-        self.setupParents()
-
-    def _create(self):
-        """ Perform device-specific create operations. """
-        pass
-
-    def create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        self._preCreate()
-        try:
-            self._create()
-        except Exception as e:
-            raise DeviceCreateError(str(e), self.name)
-        else:
-            self._postCreate()
-
-    def _postCreate(self):
-        """ Perform post-create operations. """
-        self.exists = True
-        self.setup()
-        self.updateSysfsPath()
-        udev_settle()
-
-    #
-    # destroy
-    #
-    def _preDestroy(self):
-        """ Preparation and precondition checking for device destruction. """
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not self.isleaf:
-            raise DeviceError("Cannot destroy non-leaf device", self.name)
-
-        self.teardown()
-
-    def _destroy(self):
-        """ Perform device-specific destruction operations. """
-        pass
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        self._preDestroy()
-        self._destroy()
-        self._postDestroy()
-
-    def _postDestroy(self):
-        """ Perform post-destruction operations. """
-        self.exists = False
-
-    def setupParents(self, orig=False):
-        """ Run setup method of all parent devices. """
-        log_method_call(self, name=self.name, orig=orig, kids=self.kids)
-        for parent in self.parents:
-            parent.setup(orig=orig)
-            if orig:
-                _format = parent.originalFormat
-            else:
-                _format = parent.format
-
-            # set up the formatting, if present
-            if _format.type and _format.exists:
-                _format.setup()
-
-    def _getSize(self):
-        """ Get the device's size in MB, accounting for pending changes. """
-        if self.exists and not self.mediaPresent:
-            return 0
-
-        if self.exists and self.partedDevice:
-            self._size = self.currentSize
-
-        size = self._size
-        if self.exists and self.resizable and self.targetSize != size:
-            size = self.targetSize
-
-        return size
-
-    def _setSize(self, newsize):
-        """ Set the device's size to a new value. """
-        if newsize > self.maxSize:
-            raise DeviceError("device cannot be larger than %s MB" %
-                              (self.maxSize,), self.name)
-        self._size = newsize
-
-    size = property(lambda x: x._getSize(),
-                    lambda x, y: x._setSize(y),
-                    doc="The device's size in MB, accounting for pending changes")
-
-    @property
-    def currentSize(self):
-        """ The device's actual size. """
-        size = 0
-        if self.exists and self.partedDevice:
-            size = self.partedDevice.getSize()
-        elif self.exists:
-            size = self._size
-        return size
-
-    @property
-    def minSize(self):
-        """ The minimum size this device can be. """
-        if self.format.minSize:
-            return self.format.minSize
-        else:
-            return self.size
-
-    @property
-    def maxSize(self):
-        """ The maximum size this device can be. """
-        if self.format.maxSize > self.currentSize:
-            return self.currentSize
-        else:
-            return self.format.maxSize
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        if not self.exists:
-            return False
-        return os.access(self.path, os.W_OK)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        if not format:
-            format = getFormat(None, device=self.path, exists=self.exists)
-        log_method_call(self, self.name, type=format.type,
-                        current=getattr(self._format, "type", None))
-        if self._format and self._format.status:
-            # FIXME: self.format.status doesn't mean much
-            raise DeviceError("cannot replace active format", self.name)
-
-        self._format = format
-        self._format.device = self.path
-
-    def _getFormat(self):
-        return self._format
-
-    format = property(lambda d: d._getFormat(),
-                      lambda d,f: d._setFormat(f),
-                      doc="The device's formatting.")
-
-    def preCommitFixup(self, *args, **kwargs):
-        """ Do any necessary pre-commit fixups."""
-        pass
-
-    @property
-    def removable(self):
-        devpath = os.path.normpath("/sys/%s" % self.sysfsPath)
-        remfile = os.path.normpath("%s/removable" % devpath)
-        return (self.sysfsPath and os.path.exists(devpath) and
-                os.access(remfile, os.R_OK) and
-                open(remfile).readline().strip() == "1")
-
-    @property
-    def isDisk(self):
-        return self._isDisk
-
-    @property
-    def partitionable(self):
-        return self._partitionable
-
-    @property
-    def partitioned(self):
-        return self.format.type == "disklabel" and self.partitionable
-
-    @property
-    def serial(self):
-        return self._serial
-
-    @property
-    def model(self):
-        if not self._model:
-            self._model = getattr(self.partedDevice, "model", "")
-        return self._model
-
-    @property
-    def vendor(self):
-        return self._vendor
-
-    @property
-    def growable(self):
-        """ True if this device or it's component devices are growable. """
-        grow = getattr(self, "req_grow", False)
-        if not grow:
-            for parent in self.parents:
-                grow = parent.growable
-                if grow:
-                    break
-        return grow
-
-    def checkSize(self):
-        """ Check to make sure the size of the device is allowed by the
-            format used.
-
-            Returns:
-            0  - ok
-            1  - Too large
-            -1 - Too small
-        """
-        if self.format.maxSize and self.size > self.format.maxSize:
-            return 1
-        elif self.format.minSize and self.size < self.format.minSize:
-            return -1
-        return 0
-
-class DiskDevice(StorageDevice):
-    """ A disk """
-    _type = "disk"
-    _partitionable = True
-    _isDisk = True
-
-    def __init__(self, name, format=None,
-                 size=None, major=None, minor=None, sysfsPath='',
-                 parents=None, serial=None, vendor="", model="", bus="",
-                 exists=True):
-        """ Create a DiskDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                major -- the device major
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                removable -- whether or not this is a removable device
-                serial -- the ID_SERIAL_SHORT for this device
-                vendor -- the manufacturer of this Device
-                model -- manufacturer's device model string
-                bus -- the interconnect this device uses
-
-
-            DiskDevices always exist.
-        """
-        StorageDevice.__init__(self, name, format=format, size=size,
-                               major=major, minor=minor, exists=exists,
-                               sysfsPath=sysfsPath, parents=parents,
-                               serial=serial, model=model,
-                               vendor=vendor, bus=bus)
-
-    def __repr__(self):
-        s = StorageDevice.__repr__(self)
-        s += ("  removable = %(removable)s  partedDevice = %(partedDevice)r" %
-              {"removable": self.removable, "partedDevice": self.partedDevice})
-        return s
-
-    @property
-    def mediaPresent(self):
-        if flags.testing:
-            return True
-
-        if not self.partedDevice:
-            return False
-
-        # Some drivers (cpqarray <blegh>) make block device nodes for
-        # controllers with no disks attached and then report a 0 size,
-        # treat this as no media present
-        return self.partedDevice.getSize() != 0
-
-    @property
-    def description(self):
-        return self.model
-
-    @property
-    def size(self):
-        """ The disk's size in MB """
-        return super(DiskDevice, self).size
-    #size = property(StorageDevice._getSize)
-
-    def _preDestroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.mediaPresent:
-            raise DeviceError("cannot destroy disk with no media", self.name)
-
-        StorageDevice._preDestroy(self)
-
-
-class PartitionDevice(StorageDevice):
-    """ A disk partition.
-
-        On types and flags...
-
-        We don't need to deal with numerical partition types at all. The
-        only type we are concerned with is primary/logical/extended. Usage
-        specification is accomplished through the use of flags, which we
-        will set according to the partition's format.
-    """
-    _type = "partition"
-    _resizable = True
-    defaultSize = 500
-
-    def __init__(self, name, format=None,
-                 size=None, grow=False, maxsize=None,
-                 major=None, minor=None, bootable=None,
-                 sysfsPath='', parents=None, exists=False,
-                 partType=None, primary=False, weight=0):
-        """ Create a PartitionDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                exists -- indicates whether this is an existing device
-                format -- the device's format (DeviceFormat instance)
-
-                For existing partitions:
-
-                    parents -- the disk that contains this partition
-                    major -- the device major
-                    minor -- the device minor
-                    sysfsPath -- sysfs device path
-
-                For new partitions:
-
-                    partType -- primary,extended,&c (as parted constant)
-                    grow -- whether or not to grow the partition
-                    maxsize -- max size for growable partitions (in MB)
-                    size -- the device's size (in MB)
-                    bootable -- whether the partition is bootable
-                    parents -- a list of potential containing disks
-                    weight -- an initial sorting weight to assign
-        """
-        self.req_disks = []
-        self.req_partType = None
-        self.req_primary = None
-        self.req_grow = None
-        self.req_bootable = None
-        self.req_size = 0
-        self.req_base_size = 0
-        self.req_max_size = 0
-        self.req_base_weight = 0
-
-        self._bootable = False
-
-        StorageDevice.__init__(self, name, format=format, size=size,
-                               major=major, minor=minor, exists=exists,
-                               sysfsPath=sysfsPath, parents=parents)
-
-        if not exists:
-            # this is a request, not a partition -- it has no parents
-            self.req_disks = self.parents[:]
-            for dev in self.parents:
-                dev.removeChild()
-            self.parents = []
-
-        # FIXME: Validate partType, but only if this is a new partition
-        #        Otherwise, overwrite it with the partition's type.
-        self._partType = None
-        self.partedFlags = {}
-        self._partedPartition = None
-        self._origPath = None
-        self._currentSize = 0
-
-        # FIXME: Validate size, but only if this is a new partition.
-        #        For existing partitions we will get the size from
-        #        parted.
-
-        if self.exists and not flags.testing:
-            log.debug("looking up parted Partition: %s" % self.path)
-            self._partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path)
-            if not self._partedPartition:
-                raise DeviceError("cannot find parted partition instance", self.name)
-
-            self._origPath = self.path
-            # collect information about the partition from parted
-            self.probe()
-            if self.getFlag(parted.PARTITION_PREP):
-                # the only way to identify a PPC PReP Boot partition is to
-                # check the partition type/flags, so do it here.
-                self.format = getFormat("prepboot", device=self.path, exists=True)
-            elif self.getFlag(parted.PARTITION_BIOS_GRUB):
-                # the only way to identify a BIOS Boot partition is to
-                # check the partition type/flags, so do it here.
-                self.format = getFormat("biosboot", device=self.path, exists=True)
-        else:
-            # XXX It might be worthwhile to create a shit-simple
-            #     PartitionRequest class and pass one to this constructor
-            #     for new partitions.
-            if not self._size:
-                # default size for new partition requests
-                self._size = self.defaultSize
-            self.req_name = name
-            self.req_partType = partType
-            self.req_primary = primary
-            self.req_max_size = util.numeric_type(maxsize)
-            self.req_grow = grow
-            self.req_bootable = bootable
-
-            # req_size may be manipulated in the course of partitioning
-            self.req_size = self._size
-
-            # req_base_size will always remain constant
-            self.req_base_size = self._size
-
-            self.req_base_weight = weight
-
-    def __repr__(self):
-        s = StorageDevice.__repr__(self)
-        s += ("  grow = %(grow)s  max size = %(maxsize)s  bootable = %(bootable)s\n"
-              "  part type = %(partType)s  primary = %(primary)s\n"
-              "  partedPartition = %(partedPart)s\n"
-              "  disk = %(disk)s\n" %
-              {"grow": self.req_grow, "maxsize": self.req_max_size,
-               "bootable": self.bootable, "partType": self.partType,
-               "primary": self.req_primary,
-               "partedPart": self.partedPartition, "disk": self.disk})
-
-        if self.partedPartition:
-            s += ("  start = %(start)s  end = %(end)s  length = %(length)s\n"
-                  "  flags = %(flags)s" %
-                  {"length": self.partedPartition.geometry.length,
-                   "start": self.partedPartition.geometry.start,
-                   "end": self.partedPartition.geometry.end,
-                   "flags": self.partedPartition.getFlagsAsString()})
-
-        return s
-
-    @property
-    def dict(self):
-        d = super(PartitionDevice, self).dict
-        d.update({"type": self.partType})
-        if not self.exists:
-            d.update({"grow": self.req_grow, "maxsize": self.req_max_size,
-                      "bootable": self.bootable,
-                      "primary": self.req_primary})
-
-        if self.partedPartition:
-            d.update({"length": self.partedPartition.geometry.length,
-                      "start": self.partedPartition.geometry.start,
-                      "end": self.partedPartition.geometry.end,
-                      "flags": self.partedPartition.getFlagsAsString()})
-        return d
-
-    def _setTargetSize(self, newsize):
-        if newsize != self.currentSize:
-            # change this partition's geometry in-memory so that other
-            # partitioning operations can complete (e.g., autopart)
-            self._targetSize = newsize
-            disk = self.disk.format.partedDisk
-
-            # resize the partition's geometry in memory
-            (constraint, geometry) = self._computeResize(self.partedPartition)
-            disk.setPartitionGeometry(partition=self.partedPartition,
-                                      constraint=constraint,
-                                      start=geometry.start, end=geometry.end)
-
-    @property
-    def path(self):
-        if not self.parents:
-            devDir = StorageDevice._devDir
-        else:
-            devDir = self.parents[0]._devDir
-
-        return "%s/%s" % (devDir, self.name)
-
-    @property
-    def partType(self):
-        """ Get the partition's type (as parted constant). """
-        try:
-            ptype = self.partedPartition.type
-        except AttributeError:
-            ptype = self._partType
-
-        if not self.exists and ptype is None:
-            ptype = self.req_partType
-
-        return ptype
-
-    @property
-    def isExtended(self):
-        return (self.partType is not None and
-                self.partType & parted.PARTITION_EXTENDED)
-
-    @property
-    def isLogical(self):
-        return (self.partType is not None and
-                self.partType & parted.PARTITION_LOGICAL)
-
-    @property
-    def isPrimary(self):
-        return (self.partType is not None and
-                self.partType == parted.PARTITION_NORMAL)
-
-    @property
-    def isProtected(self):
-        return (self.partType is not None and
-                self.partType & parted.PARTITION_PROTECTED)
-
-    @property
-    def fstabSpec(self):
-        spec = self.path
-        if self.disk and self.disk.type == 'dasd':
-            spec = deviceNameToDiskByPath(self.name)
-        elif self.format and self.format.uuid:
-            spec = "UUID=%s" % self.format.uuid
-        return spec
-
-    def _getPartedPartition(self):
-        return self._partedPartition
-
-    def _setPartedPartition(self, partition):
-        """ Set this PartitionDevice's parted Partition instance. """
-        log_method_call(self, self.name)
-        if partition is None:
-            path = None
-        elif isinstance(partition, parted.Partition):
-            path = partition.path
-        else:
-            raise ValueError("partition must be a parted.Partition instance")
-
-        log.debug("device %s new partedPartition %s" % (self.name, partition))
-        self._partedPartition = partition
-        self.updateName()
-
-    partedPartition = property(lambda d: d._getPartedPartition(),
-                               lambda d,p: d._setPartedPartition(p))
-
-    def preCommitFixup(self, *args, **kwargs):
-        """ Re-get self.partedPartition from the original disklabel. """
-        log_method_call(self, self.name)
-        if not self.exists:
-            return
-
-        # find the correct partition on the original parted.Disk since the
-        # name/number we're now using may no longer match
-        _disklabel = self.disk.originalFormat
-
-        if self.isExtended:
-            # getPartitionBySector doesn't work on extended partitions
-            _partition = _disklabel.extendedPartition
-            log.debug("extended lookup found partition %s"
-                        % devicePathToName(getattr(_partition, "path", None)))
-        else:
-            # lookup the partition by sector to avoid the renumbering
-            # nonsense entirely
-            _sector = self.partedPartition.geometry.start
-            _partition = _disklabel.partedDisk.getPartitionBySector(_sector)
-            log.debug("sector-based lookup found partition %s"
-                        % devicePathToName(getattr(_partition, "path", None)))
-
-        self.partedPartition = _partition
-
-    def _getWeight(self):
-        return self.req_base_weight
-
-    def _setWeight(self, weight):
-        self.req_base_weight = weight
-
-    weight = property(lambda d: d._getWeight(),
-                      lambda d,w: d._setWeight(w))
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.parents:
-            self.sysfsPath = ''
-
-        elif isinstance(self.parents[0], DMDevice):
-            dm_node = dm.dm_node_from_name(self.name)
-            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-        elif isinstance(self.parents[0], MDRaidArrayDevice):
-            md_node = mdraid.md_node_from_name(self.name)
-            path = os.path.join("/sys", self.sysfsBlockDir, md_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-        else:
-            StorageDevice.updateSysfsPath(self)
-
-    def updateName(self):
-        if self.partedPartition is None:
-            self._name = self.req_name
-        else:
-            self._name = \
-                devicePathToName(self.partedPartition.getDeviceNodeName())
-
-    def dependsOn(self, dep):
-        """ Return True if this device depends on dep. """
-        if isinstance(dep, PartitionDevice) and dep.isExtended and \
-           self.isLogical and self.disk == dep.disk:
-            return True
-
-        return Device.dependsOn(self, dep)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        log_method_call(self, self.name)
-        StorageDevice._setFormat(self, format)
-
-    def _setBootable(self, bootable):
-        """ Set the bootable flag for this partition. """
-        if self.partedPartition:
-            if arch.isS390():
-                return
-            if self.flagAvailable(parted.PARTITION_BOOT):
-                if bootable:
-                    self.setFlag(parted.PARTITION_BOOT)
-                else:
-                    self.unsetFlag(parted.PARTITION_BOOT)
-            else:
-                raise DeviceError("boot flag not available for this partition", self.name)
-
-            self._bootable = bootable
-        else:
-            self.req_bootable = bootable
-
-    def _getBootable(self):
-        return self._bootable or self.req_bootable
-
-    bootable = property(_getBootable, _setBootable)
-
-    def flagAvailable(self, flag):
-        if not self.partedPartition:
-            return
-
-        return self.partedPartition.isFlagAvailable(flag)
-
-    def getFlag(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        return self.partedPartition.getFlag(flag)
-
-    def setFlag(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        self.partedPartition.setFlag(flag)
-
-    def unsetFlag(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        self.partedPartition.unsetFlag(flag)
-
-    @property
-    def isMagic(self):
-        if not self.disk:
-            return False
-
-        number = getattr(self.partedPartition, "number", -1)
-        magic = self.disk.format.magicPartitionNumber
-        return (number == magic)
-
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            size, partition type, flags
-        """
-        log_method_call(self, self.name, exists=self.exists)
-        if not self.exists:
-            return
-
-        # this is in MB
-        self._size = self.partedPartition.getSize()
-        self._currentSize = self._size
-        self.targetSize = self._size
-
-        self._partType = self.partedPartition.type
-
-        self._bootable = self.getFlag(parted.PARTITION_BOOT)
-
-    def _create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        self.disk.format.addPartition(self.partedPartition)
-
-        try:
-            self.disk.format.commit()
-        except DiskLabelCommitError:
-            part = self.disk.format.partedDisk.getPartitionByPath(self.path)
-            self.disk.format.removePartition(part)
-            raise
-
-    def _postCreate(self):
-        if self.isExtended:
-            partition = self.disk.format.extendedPartition
-        else:
-            start = self.partedPartition.geometry.start
-            partition = self.disk.format.partedDisk.getPartitionBySector(start)
-
-        log.debug("post-commit partition path is %s" % getattr(partition,
-                                                               "path", None))
-        self.partedPartition = partition
-        if not self.isExtended:
-            # Ensure old metadata which lived in freespace so did not get
-            # explictly destroyed by a destroyformat action gets wiped
-            DeviceFormat(device=self.path, exists=True).destroy()
-
-        StorageDevice._postCreate(self)
-        self._currentSize = self.partedPartition.getSize()
-
-    def _computeResize(self, partition):
-        log_method_call(self, self.name, status=self.status)
-
-        # compute new size for partition
-        currentGeom = partition.geometry
-        currentDev = currentGeom.device
-        newLen = long(self.targetSize * 1024 * 1024) / currentDev.sectorSize
-        newGeometry = parted.Geometry(device=currentDev,
-                                      start=currentGeom.start,
-                                      length=newLen)
-        # and align the end sector
-        newGeometry.end = self.disk.format.endAlignment.alignDown(newGeometry,
-                                                               newGeometry.end)
-        constraint = parted.Constraint(exactGeom=newGeometry)
-
-        return (constraint, newGeometry)
-
-    def resize(self):
-        """ Resize the device.
-
-            self.targetSize must be set to the new size.
-        """
-        log_method_call(self, self.name, status=self.status)
-        self._preDestroy()
-        if self.targetSize != self.currentSize:
-            # partedDisk has been restored to _origPartedDisk, so
-            # recalculate resize geometry because we may have new
-            # partitions on the disk, which could change constraints
-            partedDisk = self.disk.format.partedDisk
-            partition = partedDisk.getPartitionByPath(self.path)
-            (constraint, geometry) = self._computeResize(partition)
-
-            partedDisk.setPartitionGeometry(partition=partition,
-                                            constraint=constraint,
-                                            start=geometry.start,
-                                            end=geometry.end)
-
-            self.disk.format.commit()
-            self._currentSize = partition.getSize()
-
-    def _preDestroy(self):
-        StorageDevice._preDestroy(self)
-        if not self.sysfsPath:
-            return
-
-        self.setupParents(orig=True)
-
-    def _destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        # we should have already set self.partedPartition to point to the
-        # partition on the original disklabel
-        self.disk.originalFormat.removePartition(self.partedPartition)
-        try:
-            self.disk.originalFormat.commit()
-        except DiskLabelCommitError:
-            self.disk.originalFormat.addPartition(self.partedPartition)
-            self.partedPartition = self.disk.originalFormat.partedDisk.getPartitionByPath(self.path)
-            raise
-
-        if self.disk.format.exists and \
-           self.disk.format.partedDisk != self.disk.originalFormat.partedDisk:
-            # If the new/current disklabel is the same as the original one, we
-            # have to duplicate the removal on the other copy of the DiskLabel.
-            part = self.disk.format.partedDisk.getPartitionByPath(self.path)
-            self.disk.format.removePartition(part)
-            self.disk.format.commit()
-
-    def deactivate(self):
-        """
-        This is never called. For instructional purposes only.
-
-        We do not want multipath partitions disappearing upon their teardown().
-        """
-        if self.parents[0].type == 'dm-multipath':
-            devmap = block.getMap(major=self.major, minor=self.minor)
-            if devmap:
-                try:
-                    block.removeDeviceMap(devmap)
-                except Exception as e:
-                    raise DeviceTeardownError("failed to tear down device-mapper partition %s: %s" % (self.name, e))
-            udev_settle()
-
-    def _getSize(self):
-        """ Get the device's size. """
-        size = self._size
-        if self.partedPartition:
-            # this defaults to MB
-            size = self.partedPartition.getSize()
-        return size
-
-    def _setSize(self, newsize):
-        """ Set the device's size (for resize, not creation).
-
-            Arguments:
-
-                newsize -- the new size (in MB)
-
-        """
-        log_method_call(self, self.name,
-                        status=self.status, size=self._size, newsize=newsize)
-        if not self.exists:
-            raise DeviceError("device does not exist", self.name)
-
-        if newsize > self.disk.size:
-            raise ValueError("partition size would exceed disk size")
-
-        # this defaults to MB
-        maxAvailableSize = self.partedPartition.getMaxAvailableSize()
-
-        if newsize > maxAvailableSize:
-            raise ValueError("new size is greater than available space")
-
-         # now convert the size to sectors and update the geometry
-        geometry = self.partedPartition.geometry
-        physicalSectorSize = geometry.device.physicalSectorSize
-
-        new_length = (newsize * (1024 * 1024)) / physicalSectorSize
-        geometry.length = new_length
-
-    def _getDisk(self):
-        """ The disk that contains this partition."""
-        try:
-            disk = self.parents[0]
-        except IndexError:
-            disk = None
-        return disk
-
-    def _setDisk(self, disk):
-        """Change the parent.
-
-        Setting up a disk is not trivial.  It has the potential to change
-        the underlying object.  If necessary we must also change this object.
-        """
-        log_method_call(self, self.name, old=getattr(self.disk, "name", None),
-                        new=getattr(disk, "name", None))
-        if self.disk:
-            self.disk.removeChild()
-
-        if disk:
-            self.parents = [disk]
-            disk.addChild()
-        else:
-            self.parents = []
-
-    disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))
-
-    @property
-    def maxSize(self):
-        """ The maximum size this partition can be. """
-        # XXX Only allow growth up to the amount of free space following this
-        #     partition on disk. We don't care about leading free space --
-        #     a filesystem cannot be relocated, so if you want to use space
-        #     before and after your partition, remove it and create a new one.
-        sector = self.partedPartition.geometry.end + 1
-        maxPartSize = self.size
-        try:
-            partition = self.partedPartition.disk.getPartitionBySector(sector)
-        except _ped.PartitionException:
-            pass
-        else:
-            if partition.type == parted.PARTITION_FREESPACE:
-                maxPartSize = self.size + math.floor(partition.getSize())
-
-        return min(self.format.maxSize, maxPartSize)
-
-    @property
-    def currentSize(self):
-        """ The device's actual size. """
-        if self.exists:
-            return self._currentSize
-        else:
-            return 0
-
-    @property
-    def resizable(self):
-        """ Can this type of device be resized? """
-        return super(PartitionDevice, self).resizable and \
-               self.disk.type != 'dasd'
-
-    def checkSize(self):
-        """ Check to make sure the size of the device is allowed by the
-            format used.
-
-            Returns:
-            0  - ok
-            1  - Too large
-            -1 - Too small
-        """
-        if self.format.maxSize and self.size > self.format.maxSize:
-            return 1
-        elif (self.format.minSize and
-              (not self.req_grow and
-               self.size < self.format.minSize) or
-              (self.req_grow and self.req_max_size and
-               self.req_max_size < self.format.minSize)):
-            return -1
-        return 0
-
-class DMDevice(StorageDevice):
-    """ A device-mapper device """
-    _type = "dm"
-    _devDir = "/dev/mapper"
-
-    def __init__(self, name, format=None, size=None, dmUuid=None,
-                 target=None, exists=False, parents=None, sysfsPath=''):
-        """ Create a DMDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                target -- the device-mapper target type (string)
-                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
-        """
-        StorageDevice.__init__(self, name, format=format, size=size,
-                               exists=exists,
-                               parents=parents, sysfsPath=sysfsPath)
-        self.target = target
-        self.dmUuid = dmUuid
-
-    def __repr__(self):
-        s = StorageDevice.__repr__(self)
-        s += ("  target = %(target)s  dmUuid = %(dmUuid)s" %
-              {"target": self.target, "dmUuid": self.dmUuid})
-        return s
-
-    @property
-    def dict(self):
-        d = super(DMDevice, self).dict
-        d.update({"target": self.target, "dmUuid": self.dmUuid})
-        return d
-
-    @property
-    def fstabSpec(self):
-        """ Return the device specifier for use in /etc/fstab. """
-        return self.path
-
-    @property
-    def mapName(self):
-        """ This device's device-mapper map name """
-        return self.name
-
-    @property
-    def status(self):
-        _status = False
-        for map in block.dm.maps():
-            if map.name == self.mapName:
-                _status = map.live_table and not map.suspended
-                break
-
-        return _status
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            dm_node = self.getDMNode()
-            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-        else:
-            self.sysfsPath = ''
-
-    #def getTargetType(self):
-    #    return dm.getDmTarget(name=self.name)
-
-    def getDMNode(self):
-        """ Return the dm-X (eg: dm-0) device node for this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        return dm.dm_node_from_name(self.name)
-
-    def setupPartitions(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        rc = util.run_program(["kpartx", "-a", "-s", self.path])
-        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 = util.run_program(["kpartx", "-d", "-s", self.path])
-        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)
-        if self.status:
-            raise DeviceError("cannot rename active device", self.name)
-
-        self._name = name
-        #self.sysfsPath = "/dev/disk/by-id/dm-name-%s" % self.name
-
-    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=False, 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")
-
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath,
-                          exists=exists, target="linear", dmUuid=dmUuid)
-
-    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)
-        slave_length = self.slave.partedDevice.length
-        dm.dm_create_linear(self.name, self.slave.path, slave_length,
-                            self.dmUuid)
-
-    def _postSetup(self):
-        StorageDevice._postSetup(self)
-        self.setupPartitions()
-        udev_settle()
-
-    def _teardown(self, recursive=False):
-        self.teardownPartitions()
-        udev_settle()
-        dm.dm_remove(self.name)
-        udev_settle()
-
-    def deactivate(self, recursive=False):
-        StorageDevice.teardown(self, recursive=recursive)
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-        if not self._preTeardown(recursive=recursive):
-            return
-
-        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 """
-    _type = "dm-crypt"
-
-    def __init__(self, name, format=None, size=None, uuid=None,
-                 exists=False, sysfsPath='', parents=None):
-        """ Create a DMCryptDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                exists -- indicates whether this is an existing device
-        """
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath,
-                          exists=exists, target="crypt")
-
-class LUKSDevice(DMCryptDevice):
-    """ A mapped LUKS device. """
-    _type = "luks/dm-crypt"
-    _packages = ["cryptsetup-luks"]
-
-    def __init__(self, name, format=None, size=None, uuid=None,
-                 exists=False, sysfsPath='', parents=None):
-        """ Create a LUKSDevice instance.
-
-            Arguments:
-
-                name -- the device name
-
-            Keyword Arguments:
-
-                size -- the device's size in MB
-                uuid -- the device's UUID
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                exists -- indicates whether this is an existing device
-        """
-        DMCryptDevice.__init__(self, name, format=format, size=size,
-                               parents=parents, sysfsPath=sysfsPath,
-                               uuid=None, exists=exists)
-
-    @property
-    def size(self):
-        if not self.exists or not self.partedDevice:
-            size = float(self.slave.size) - crypto.LUKS_METADATA_SIZE
-        else:
-            size = self.partedDevice.getSize()
-        return size
-
-    def _postCreate(self):
-        self._name = self.slave.format.mapName
-        StorageDevice._postCreate(self)
-
-    def _postTeardown(self, recursive=False):
-        if not recursive:
-            # this is handled by StorageDevice._postTeardown if recursive
-            # is True
-            self.teardownParents(recursive=recursive)
-
-        StorageDevice._postTeardown(self, recursive=recursive)
-
-    def dracutSetupArgs(self):
-        return set(["rd.luks.uuid=luks-%s" % self.slave.format.uuid])
-
-class LVMVolumeGroupDevice(DMDevice):
-    """ An LVM Volume Group
-
-        XXX Maybe this should inherit from StorageDevice instead of
-            DMDevice since there's no actual device.
-    """
-    _type = "lvmvg"
-    _packages = ["lvm2"]
-
-    def __init__(self, name, parents=None, size=None, free=None,
-                 peSize=None, peCount=None, peFree=None, pvCount=None,
-                 uuid=None, exists=False, sysfsPath=''):
-        """ Create a LVMVolumeGroupDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                parents -- a list of physical volumes (StorageDevice)
-
-            Keyword Arguments:
-
-                peSize -- physical extent size (in MB)
-                exists -- indicates whether this is an existing device
-                sysfsPath -- sysfs device path
-
-                For existing VG's only:
-
-                    size -- the VG's size (in MB)
-                    free -- amount of free space in the VG
-                    peFree -- number of free extents
-                    peCount -- total number of extents
-                    pvCount -- number of PVs in this VG
-                    uuid -- the VG's UUID
-
-        """
-        self.pvClass = get_device_format_class("lvmpv")
-        if not self.pvClass:
-            raise StorageError("cannot find 'lvmpv' class")
-
-        if isinstance(parents, list):
-            for dev in parents:
-                if not isinstance(dev.format, self.pvClass):
-                    raise ValueError("constructor requires a list of PVs")
-        elif not isinstance(parents.format, self.pvClass):
-            raise ValueError("constructor requires a list of PVs")
-
-        DMDevice.__init__(self, name, parents=parents,
-                          exists=exists, sysfsPath=sysfsPath)
-
-        self.uuid = uuid
-        self.free = util.numeric_type(free)
-        self.peSize = util.numeric_type(peSize)
-        self.peCount = util.numeric_type(peCount)
-        self.peFree = util.numeric_type(peFree)
-        self.pvCount = util.numeric_type(pvCount)
-        self.lv_names = []
-        self.lv_uuids = []
-        self.lv_sizes = []
-        self.lv_attr = []
-        self.hasDuplicate = False
-        self.reserved_percent = 0
-        self.reserved_space = 0
-
-        # circular references, here I come
-        self._lvs = []
-
-        # TODO: validate peSize if given
-        if not self.peSize:
-            self.peSize = lvm.LVM_PE_SIZE  # MB
-
-        if not self.exists:
-            self.pvCount = len(self.parents)
-
-        # Some snapshots don't have a proper LV as an origin (--vorigin).
-        # They still occupy space in the VG.
-        self.voriginSnapshots = {}
-
-    def __repr__(self):
-        s = DMDevice.__repr__(self)
-        s += ("  free = %(free)s  PE Size = %(peSize)s  PE Count = %(peCount)s\n"
-              "  PE Free = %(peFree)s  PV Count = %(pvCount)s\n"
-              "  LV Names = %(lv_names)s  modified = %(modified)s\n"
-              "  extents = %(extents)s  free space = %(freeSpace)s\n"
-              "  free extents = %(freeExtents)s"
-              "  reserved percent = %(rpct)s  reserved space = %(res)s\n"
-              "  PVs = %(pvs)s\n"
-              "  LVs = %(lvs)s" %
-              {"free": self.free, "peSize": self.peSize, "peCount": self.peCount,
-               "peFree": self.peFree, "pvCount": self.pvCount,
-               "lv_names": self.lv_names, "modified": self.isModified,
-               "extents": self.extents, "freeSpace": self.freeSpace,
-               "freeExtents": self.freeExtents,
-               "rpct": self.reserved_percent, "res": self.reserved_space,
-               "pvs": pprint.pformat([str(p) for p in self.pvs]),
-               "lvs": pprint.pformat([str(l) for l in self.lvs])})
-        return s
-
-    @property
-    def dict(self):
-        d = super(LVMVolumeGroupDevice, self).dict
-        d.update({"free": self.free, "peSize": self.peSize,
-                  "peCount": self.peCount, "peFree": self.peFree,
-                  "pvCount": self.pvCount, "extents": self.extents,
-                  "freeSpace": self.freeSpace,
-                  "freeExtents": self.freeExtents,
-                  "lv_names": self.lv_names,
-                  "lv_uuids": self.lv_uuids,
-                  "lv_sizes": self.lv_sizes,
-                  "lv_attr": self.lv_attr,
-                  "reserved_percent": self.reserved_percent,
-                  "reserved_space": self.reserved_space,
-                  "lvNames": [lv.name for lv in self.lvs]})
-        return d
-
-    @property
-    def mapName(self):
-        """ This device's device-mapper map name """
-        # Thank you lvm for this lovely hack.
-        return self.name.replace("-","--")
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.mapName)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        self.sysfsPath = ''
-
-    @property
-    def status(self):
-        """ The device's status (True means active). """
-        if not self.exists:
-            return False
-
-        # certainly if any of this VG's LVs are active then so are we
-        for lv in self.lvs:
-            if lv.status:
-                return True
-
-        # if any of our PVs are not active then we cannot be
-        for pv in self.pvs:
-            if not pv.status:
-                return False
-
-        # if we are missing some of our PVs we cannot be active
-        if not self.complete:
-            return False
-
-        return True
-
-    def _addDevice(self, device):
-        """ Add a new physical volume device to the volume group.
-
-            XXX This is for use by device probing routines and is not
-                intended for modification of the VG.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        if not self.exists:
-            raise DeviceError("device does not exist", self.name)
-
-        if not isinstance(device.format, self.pvClass):
-            raise ValueError("addDevice requires a PV arg")
-
-        if self.uuid and device.format.vgUuid != self.uuid:
-            # this means there is another vg with the same name on the system
-            # set hasDuplicate which will make complete return False
-            # and let devicetree._handleInconsistencies() further handle this.
-            # Note we still add the device to our parents for use by
-            # devicetree._handleInconsistencies()
-            self.hasDuplicate = True
-
-        if device in self.pvs:
-            raise ValueError("device is already a member of this VG")
-
-        self.parents.append(device)
-        device.addChild()
-
-        # now see if the VG can be activated
-        if self.complete:
-            self.setup()
-
-    def _removeDevice(self, device):
-        """ Remove a physical volume from the volume group.
-
-            This is for cases like clearing of preexisting partitions.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        try:
-            self.parents.remove(device)
-        except ValueError:
-            raise ValueError("cannot remove non-member PV device from VG")
-
-        device.removeChild()
-
-    def _preSetup(self, orig=False):
-        if self.exists and not self.complete:
-            raise DeviceError("cannot activate VG with missing PV(s)", self.name)
-        return StorageDevice._preSetup(self, orig=orig)
-
-    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)
-
-    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)
-
-    def _preDestroy(self):
-        StorageDevice._preDestroy(self)
-        # set up the pvs since lvm needs access to them to do the vgremove
-        self.setupParents(orig=True)
-
-    def _destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.complete:
-            for pv in self.pvs:
-                # Remove the PVs from the ignore filter so we can wipe them.
-                lvm.lvm_cc_removeFilterRejectRegexp(pv.name)
-
-            # Don't run vgremove or vgreduce since there may be another VG with
-            # the same name that we want to keep/use.
-            return
-
-        lvm.vgreduce(self.name, [], rm=True)
-        lvm.vgdeactivate(self.name)
-        lvm.vgremove(self.name)
-
-    def reduce(self, pv_list):
-        """ Remove the listed PVs from the VG. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        lvm.vgreduce(self.name, pv_list)
-        # XXX do we need to notify the kernel?
-
-    def _addLogVol(self, lv):
-        """ Add an LV to this VG. """
-        if lv in self._lvs:
-            raise ValueError("lv is already part of this vg")
-
-        # verify we have the space, then add it
-        # do not verify for growing vg (because of ks)
-        if not lv.exists and not self.growable and lv.size > self.freeSpace:
-            raise DeviceError("new lv is too large to fit in free space", self.name)
-
-        log.debug("Adding %s/%dMB to %s" % (lv.name, lv.size, self.name))
-        self._lvs.append(lv)
-
-    def _removeLogVol(self, lv):
-        """ Remove an LV from this VG. """
-        if lv not in self.lvs:
-            raise ValueError("specified lv is not part of this vg")
-
-        self._lvs.remove(lv)
-
-    def _addPV(self, pv):
-        """ Add a PV to this VG. """
-        if pv in self.pvs:
-            raise ValueError("pv is already part of this vg")
-
-        # for the time being we will not allow vgextend
-        if self.exists:
-            raise DeviceError("cannot add pv to existing vg", self.name)
-
-        self.parents.append(pv)
-        pv.addChild()
-
-        # and update our pv count
-        self.pvCount = len(self.parents)
-
-    def addMember(self, member):
-        self._addPV(member)
-
-    def _removePV(self, pv):
-        """ Remove an PV from this VG. """
-        if not pv in self.pvs:
-            raise ValueError("specified pv is not part of this vg")
-
-        # for the time being we will not allow vgreduce
-        if self.exists:
-            raise DeviceError("cannot remove pv from existing vg", self.name)
-
-        self.parents.remove(pv)
-        pv.removeChild()
-
-        # and update our pv count
-        self.pvCount = len(self.parents)
-
-    def removeMember(self, member):
-        self._removePV(member)
-
-    # We can't rely on lvm to tell us about our size, free space, &c
-    # since we could have modifications queued, unless the VG and all of
-    # its PVs already exist.
-    #
-    #        -- liblvm may contain support for in-memory devices
-
-    @property
-    def isModified(self):
-        """ Return True if the VG has changes queued that LVM is unaware of. """
-        modified = True
-        if self.exists and not filter(lambda d: not d.exists, self.pvs):
-            modified = False
-
-        return modified
-
-    @property
-    def snapshotSpace(self):
-        """ Total space used by snapshots in this volume group. """
-        used = 0
-        for lv in self.lvs:
-            used += self.align(lv.snapshotSpace, roundup=True)
-
-        for (vname, vsize) in self.voriginSnapshots.items():
-            used += self.align(vsize, roundup=True)
-
-        return used
-
-    @property
-    def reservedSpace(self):
-        """ Reserved space in this VG, in MB """
-        reserved = 0
-        if self.reserved_percent > 0:
-            reserved = self.reserved_percent * 0.01 * self.size
-        elif self.reserved_space > 0:
-            reserved = self.reserved_space
-
-        return self.align(reserved, roundup=True)
-
-    @property
-    def size(self):
-        """ The size of this VG """
-        # TODO: just ask lvm if isModified returns False
-
-        # sum up the sizes of the PVs and align to pesize
-        size = 0
-        for pv in self.pvs:
-            size += max(0, self.align(pv.size - pv.format.peStart))
-
-        return size
-
-    @property
-    def extents(self):
-        """ Number of extents in this VG """
-        # TODO: just ask lvm if isModified returns False
-
-        return self.size / self.peSize
-
-    @property
-    def freeSpace(self):
-        """ The amount of free space in this VG (in MB). """
-        # TODO: just ask lvm if isModified returns False
-
-        # total the sizes of any LVs
-        log.debug("%s size is %dMB" % (self.name, self.size))
-        used = sum(lv.vgSpaceUsed for lv in self.lvs) + self.snapshotSpace
-        used += self.reservedSpace
-        free = self.size - used
-        log.debug("vg %s has %dMB free" % (self.name, free))
-        return free
-
-    @property
-    def freeExtents(self):
-        """ The number of free extents in this VG. """
-        # TODO: just ask lvm if isModified returns False
-        return self.freeSpace / self.peSize
-
-    def align(self, size, roundup=None):
-        """ Align a size to a multiple of physical extent size. """
-        size = util.numeric_type(size)
-
-        if roundup:
-            round = math.ceil
-        else:
-            round = math.floor
-
-        # we want Kbytes as a float for our math
-        size *= 1024.0
-        pesize = self.peSize * 1024.0
-        return long((round(size / pesize) * pesize) / 1024)
-
-    @property
-    def pvs(self):
-        """ A list of this VG's PVs """
-        return self.parents[:]  # we don't want folks changing our list
-
-    @property
-    def lvs(self):
-        """ A list of this VG's LVs """
-        return self._lvs[:]     # we don't want folks changing our list
-
-    @property
-    def complete(self):
-        """Check if the vg has all its pvs in the system
-        Return True if complete.
-        """
-        # vgs with duplicate names are overcomplete, which is not what we want
-        if self.hasDuplicate:
-            return False
-
-        return len(self.pvs) == self.pvCount or not self.exists
-
-
-class LVMLogicalVolumeDevice(DMDevice):
-    """ An LVM Logical Volume """
-    _type = "lvmlv"
-    _resizable = True
-    _packages = ["lvm2"]
-
-    def __init__(self, name, parents=None, size=None, uuid=None,
-                 stripes=1, logSize=0, snapshotSpace=0,
-                 format=None, exists=False, sysfsPath='',
-                 grow=None, maxsize=None, percent=None,
-                 singlePV=False):
-        """ Create a LVMLogicalVolumeDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                vgdev -- volume group (LVMVolumeGroupDevice instance)
-
-            Keyword Arguments:
-
-                size -- the device's size (in MB)
-                uuid -- the device's UUID
-                stripes -- number of copies in the vg (>1 for mirrored lvs)
-                logSize -- size of log volume (for mirrored lvs)
-                snapshotSpace -- sum of sizes of snapshots of this lv
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                exists -- indicates whether this is an existing device
-                singlePV -- if true, maps this lv to a single pv
-
-                For new (non-existent) LVs only:
-
-                    grow -- whether to grow this LV
-                    maxsize -- maximum size for growable LV (in MB)
-                    percent -- percent of VG space to take
-
-        """
-        if isinstance(parents, list):
-            if len(parents) != 1:
-                raise ValueError("constructor requires a single LVMVolumeGroupDevice instance")
-            elif not isinstance(parents[0], LVMVolumeGroupDevice):
-                raise ValueError("constructor requires a LVMVolumeGroupDevice instance")
-        elif not isinstance(parents, LVMVolumeGroupDevice):
-            raise ValueError("constructor requires a LVMVolumeGroupDevice instance")
-        DMDevice.__init__(self, name, size=size, format=format,
-                          sysfsPath=sysfsPath, parents=parents,
-                          exists=exists)
-
-        self.singlePVerr = ("%(mountpoint)s is restricted to a single "
-                            "physical volume on this platform.  No physical "
-                            "volumes available in volume group %(vgname)s "
-                            "with %(size)d MB of available space." %
-                           {'mountpoint': getattr(self.format, "mountpoint",
-                                                  "A proposed logical volume"),
-                            'vgname': self.vg.name,
-                            'size': self.size})
-
-        self.uuid = uuid
-        self.snapshotSpace = snapshotSpace
-        self.stripes = stripes
-        self.logSize = logSize
-        self.singlePV = singlePV
-
-        self.req_grow = None
-        self.req_max_size = 0
-        self.req_size = 0   
-        self.req_percent = 0
-
-        if not self.exists:
-            self.req_grow = grow
-            self.req_max_size = util.numeric_type(maxsize)
-            # XXX should we enforce that req_size be pe-aligned?
-            self.req_size = self._size
-            self.req_percent = util.numeric_type(percent)
-
-        if self.singlePV:
-            # make sure there is at least one PV that can hold this LV
-            validpvs = filter(lambda x: float(x.size) >= self.req_size,
-                              self.vg.pvs)
-            if not validpvs:
-                for dev in self.parents:
-                    dev.removeChild()
-                raise SinglePhysicalVolumeError(self.singlePVerr)
-
-        # here we go with the circular references
-        self.vg._addLogVol(self)
-
-    def __repr__(self):
-        s = DMDevice.__repr__(self)
-        s += ("  VG device = %(vgdev)r\n"
-              "  percent = %(percent)s\n"
-              "  mirrored = %(mirrored)s stripes = %(stripes)d"
-              "  snapshot total =  %(snapshots)dMB\n"
-              "  VG space used = %(vgspace)dMB" %
-              {"vgdev": self.vg, "percent": self.req_percent,
-               "mirrored": self.mirrored, "stripes": self.stripes,
-               "snapshots": self.snapshotSpace, "vgspace": self.vgSpaceUsed })
-        return s
-
-    @property
-    def dict(self):
-        d = super(LVMLogicalVolumeDevice, self).dict
-        if self.exists:
-            d.update({"mirrored": self.mirrored, "stripes": self.stripes,
-                      "snapshots": self.snapshotSpace,
-                      "vgspace": self.vgSpaceUsed})
-        else:
-            d.update({"percent": self.req_percent})
-
-        return d
-
-    @property
-    def mirrored(self):
-        return self.stripes > 1
-
-    def _setSize(self, size):
-        size = self.vg.align(util.numeric_type(size))
-        log.debug("trying to set lv %s size to %dMB" % (self.name, size))
-        if size <= self.vg.freeSpace + self.vgSpaceUsed:
-            self._size = size
-            self.targetSize = size
-        else:
-            log.debug("failed to set size: %dMB short" % (size - (self.vg.freeSpace + self.vgSpaceUsed),))
-            raise ValueError("not enough free space in volume group")
-
-    size = property(StorageDevice._getSize, _setSize)
-
-    @property
-    def vgSpaceUsed(self):
-        """ Space occupied by this LV, not including snapshots. """
-        return (self.vg.align(self.size, roundup=True) * self.stripes
-                + self.logSize)
-
-    @property
-    def vg(self):
-        """ This Logical Volume's Volume Group. """
-        return self.parents[0]
-
-    @property
-    def mapName(self):
-        """ This device's device-mapper map name """
-        # Thank you lvm for this lovely hack.
-        return "%s-%s" % (self.vg.mapName, self._name.replace("-","--"))
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.mapName)
-
-    def getDMNode(self):
-        """ Return the dm-X (eg: dm-0) device node for this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        return dm.dm_node_from_name(self.mapName)
-
-    @property
-    def name(self):
-        """ This device's name. """
-        return "%s-%s" % (self.vg.name, self._name)
-
-    @property
-    def lvname(self):
-        """ The LV's name (not including VG name). """
-        return self._name
-
-    @property
-    def complete(self):
-        """ Test if vg exits and if it has all pvs. """
-        return self.vg.complete
-
-    def setupParents(self, orig=False):
-        # parent is a vg, which has no formatting (or device for that matter)
-        Device.setupParents(self, orig=orig)
-
-    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)
-
-    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)
-
-    def _postTeardown(self, recursive=False):
-        try:
-            # It's likely that teardown of a VG will fail due to other
-            # LVs being active (filesystems mounted, &c), so don't let
-            # it bring everything down.
-            StorageDevice._postTeardown(self, recursive=recursive)
-        except StorageError:
-            if recursive:
-                log.debug("vg %s teardown failed; continuing" % self.vg.name)
-            else:
-                raise
-
-    def _create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        # should we use --zero for safety's sake?
-        if self.singlePV:
-            lvm.lvcreate(self.vg.name, self._name, self.size,
-                         pvs=self._getSinglePV())
-        else:
-            lvm.lvcreate(self.vg.name, self._name, self.size)
-
-    def _preDestroy(self):
-        StorageDevice._preDestroy(self)
-        # set up the vg's pvs so lvm can remove the lv
-        self.vg.setupParents(orig=True)
-
-    def _destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        lvm.lvremove(self.vg.name, self._name)
-
-    def _getSinglePV(self):
-        validpvs = filter(lambda x: float(x.size) >= self.size, self.vg.pvs)
-
-        if not validpvs:
-            raise SinglePhysicalVolumeError(self.singlePVerr)
-
-        return [validpvs[0].path]
-
-    def resize(self):
-        log_method_call(self, self.name, status=self.status)
-        self._preDestroy()
-
-        # Setup VG parents (in case they are dmraid partitions for example)
-        self.vg.setupParents(orig=True)
-
-        if self.originalFormat.exists:
-            self.originalFormat.teardown()
-        if self.format.exists:
-            self.format.teardown()
-
-        udev_settle()
-        lvm.lvresize(self.vg.name, self._name, self.size)
-
-    def dracutSetupArgs(self):
-        # Note no mapName usage here, this is a lvm cmdline name, which
-        # is different (ofcourse)
-        return set(["rd.lvm.lv=%s/%s" % (self.vg.name, self._name)])
-
-    def checkSize(self):
-        """ Check to make sure the size of the device is allowed by the
-            format used.
-
-            Returns:
-            0  - ok
-            1  - Too large
-            -1 - Too small
-        """
-        if self.format.maxSize and self.size > self.format.maxSize:
-            return 1
-        elif (self.format.minSize and
-              (not self.req_grow and
-               self.size < self.format.minSize) or
-              (self.req_grow and self.req_max_size and
-               self.req_max_size < self.format.minSize)):
-            return -1
-        return 0
-
-class MDRaidArrayDevice(StorageDevice):
-    """ An mdraid (Linux RAID) device. """
-    _type = "mdarray"
-    _packages = ["mdadm"]
-    _devDir = "/dev/md"
-
-    def __init__(self, name, level=None, major=None, minor=None, size=None,
-                 memberDevices=None, totalDevices=None,
-                 uuid=None, format=None, exists=False, metadataVersion=None,
-                 parents=None, sysfsPath=''):
-        """ Create a MDRaidArrayDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                level -- the device's RAID level (a string, eg: '1' or 'raid1')
-                metadataVersion -- the version of the device's md metadata
-                parents -- list of member devices (StorageDevice instances)
-                size -- the device's size (units/format TBD)
-                uuid -- the device's UUID
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                exists -- indicates whether this is an existing device
-        """
-        StorageDevice.__init__(self, name, format=format, exists=exists,
-                               major=major, minor=minor, size=size,
-                               parents=parents, sysfsPath=sysfsPath)
-
-        self.level = level
-        if level == "container":
-            self._type = "mdcontainer"
-        elif level is not None:
-            self.level = mdraid.raidLevel(level)
-
-        # For new arrays check if we have enough members
-        if (not exists and parents and
-                len(parents) < mdraid.get_raid_min_members(self.level)):
-            for dev in self.parents:
-                dev.removeChild()
-            raise DeviceError, P_("A RAID%(raidLevel)d set requires at least %(minMembers)d member",
-                                 "A RAID%(raidLevel)d set requires at least %(minMembers)d members",
-                                 mdraid.get_raid_min_members(self.level)) % \
-                                 {"raidLevel": self.level, "minMembers": mdraid.get_raid_min_members(self.level)}
-
-        self.uuid = uuid
-        self._totalDevices = util.numeric_type(totalDevices)
-        self._memberDevices = util.numeric_type(memberDevices)
-
-        self.chunkSize = 512.0 / 1024.0         # chunk size in MB
-
-        if not self.exists and not isinstance(metadataVersion, str):
-            self.metadataVersion = "default"
-        else:
-            self.metadataVersion = metadataVersion
-
-        # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
-        self.createBitmap = self.level != 0
-
-        # For container members probe size now, as we cannot determine it
-        # when teared down.
-        if self.parents and self.parents[0].type == "mdcontainer":
-            self._size = self.currentSize
-            self._type = "mdbiosraidarray"
-
-        self.formatClass = get_device_format_class("mdmember")
-        if not self.formatClass:
-            for dev in self.parents:
-                dev.removeChild()
-            raise DeviceError("cannot find class for 'mdmember'", self.name)
-
-        if self.exists and self.uuid and not flags.testing:
-            # this is a hack to work around mdadm's insistence on giving
-            # really high minors to arrays it has no config entry for
-            open("/etc/mdadm.conf", "a").write("ARRAY %s UUID=%s\n"
-                                                % (self.path, self.uuid))
-
-    @property
-    def rawArraySize(self):
-        """ Calculate the raw array size without taking into account space
-        reserved for metadata or chunkSize alignment.
-
-        This is used to calculate the superBlockSize for v1.1 and v1.2
-        metadata.
-
-        Returns the raw size in MB
-        """
-        smallestMemberSize = self.smallestMember.size
-        if self.level == mdraid.RAID0:
-            size = self.memberDevices * smallestMemberSize
-        elif self.level == mdraid.RAID1:
-            size = smallestMemberSize
-        elif self.level == mdraid.RAID4:
-            size = (self.memberDevices - 1) * smallestMemberSize
-        elif self.level == mdraid.RAID5:
-            size = (self.memberDevices - 1) * smallestMemberSize
-        elif self.level == mdraid.RAID6:
-            size = (self.memberDevices - 2) * smallestMemberSize
-        elif self.level == mdraid.RAID10:
-            size = (self.memberDevices / 2.0) * smallestMemberSize
-        else:
-            size = smallestMemberSize
-            log.error("unknown RAID level %s" % (self.level))
-        log.debug("raw RAID %s size == %s" % (self.level, size))
-        return size
-
-    @property
-    def superBlockSize(self):
-        """ mdadm has different amounts of space reserved for its use depending
-        on the metadata type and size of the array.
-
-        0.9 use 2.0 MB
-        1.0 use 2.0 MB
-        1.1 or 1.2 use the formula lifted from mdadm/super1.c to calculate it
-        based on the array size.
-        """
-        # mdadm 3.2.4 made a major change in the amount of space used for 1.1 and 1.2
-        # in order to reserve space for reshaping. See commit 508a7f16 in the
-        # upstream mdadm repository.
-        if self.metadataVersion not in ["default", "1.1", "1.2"]:
-            headroom = 2.0
-        else:
-            array_size = self.rawArraySize
-            # MDADM: We try to leave 0.1% at the start for reshape
-            # MDADM: operations, but limit this to 128Meg (0.1% of 10Gig)
-            # MDADM: which is plenty for efficient reshapes
-            # NOTE: In the mdadm code this is in 512b sectors. Converted to use MB
-            headroom = 128
-            while headroom << 10 > array_size:
-                headroom >>= 1
-        log.info("Using %sMB superBlockSize" % (headroom))
-        return headroom
-
-    @property
-    def smallestMember(self):
-        try:
-            smallest = sorted(self.devices, key=lambda d: d.size)[0]
-        except IndexError:
-            smallest = None
-        return smallest
-
-    @property
-    def size(self):
-        if not self.devices:
-            return 0
-
-        # For container members return probed size, as we cannot determine it
-        # when teared down.
-        if self.type == "mdbiosraidarray":
-            return self._size
-
-        size = 0
-        smallestMemberSize = self.smallestMember.size - self.superBlockSize
-        if not self.exists or not self.partedDevice:
-            if self.level == mdraid.RAID0:
-                size = self.memberDevices * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID1:
-                size = smallestMemberSize
-            elif self.level == mdraid.RAID4:
-                size = (self.memberDevices - 1) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID5:
-                size = (self.memberDevices - 1) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID6:
-                size = (self.memberDevices - 2) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID10:
-                size = (self.memberDevices / 2.0) * smallestMemberSize
-                size -= size % self.chunkSize
-            log.debug("non-existent RAID %s size == %s" % (self.level, size))
-        else:
-            size = self.partedDevice.getSize()
-            log.debug("existing RAID %s size == %s" % (self.level, size))
-
-        return size
-
-    @property
-    def description(self):
-        if self.level == mdraid.RAID0:
-            levelstr = "stripe"
-        elif self.level == mdraid.RAID1:
-            levelstr = "mirror"
-        else:
-            levelstr = "raid%s" % self.level
-
-        if self.type == "mdcontainer":
-            return "BIOS RAID container"
-        elif self.type == "mdbiosraidarray":
-            return "BIOS RAID set (%s)" % levelstr
-        else:
-            return "MDRAID set (%s)" % levelstr
-
-    def __repr__(self):
-        s = StorageDevice.__repr__(self)
-        s += ("  level = %(level)s  spares = %(spares)s\n"
-              "  members = %(memberDevices)s\n"
-              "  total devices = %(totalDevices)s"
-              "  metadata version = %(metadataVersion)s" %
-              {"level": self.level, "spares": self.spares,
-               "memberDevices": self.memberDevices,
-               "totalDevices": self.totalDevices,
-               "metadataVersion": self.metadataVersion})
-        return s
-
-    @property
-    def dict(self):
-        d = super(MDRaidArrayDevice, self).dict
-        d.update({"level": self.level,
-                  "spares": self.spares, "memberDevices": self.memberDevices,
-                  "totalDevices": self.totalDevices,
-                  "metadataVersion": self.metadataVersion})
-        return d
-
-    @property
-    def mdadmConfEntry(self):
-        """ This array's mdadm.conf entry. """
-        if self.level is None or self.memberDevices is None or not self.uuid:
-            raise DeviceError("array is not fully defined", self.name)
-
-        # containers and the sets within must only have a UUID= parameter
-        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
-            fmt = "ARRAY %s UUID=%s\n"
-            return fmt % (self.path, self.uuid)
-
-        fmt = "ARRAY %s level=raid%d num-devices=%d UUID=%s\n"
-        return fmt % (self.path, self.level, self.memberDevices, self.uuid)
-
-    @property
-    def totalDevices(self):
-        """ Total number of devices in the array, including spares. """
-        count = len(self.parents)
-        if not self.exists:
-            count = self._totalDevices
-        return count
-
-    def _getMemberDevices(self):
-        return self._memberDevices
-
-    def _setMemberDevices(self, number):
-        if not isinstance(number, int):
-            raise ValueError("memberDevices is an integer")
-
-        if number > self.totalDevices:
-            raise ValueError("memberDevices cannot be greater than totalDevices")
-        self._memberDevices = number
-
-    memberDevices = property(_getMemberDevices, _setMemberDevices,
-                             doc="number of member devices")
-
-    def _getSpares(self):
-        spares = 0
-        if self.memberDevices is not None:
-            if self.totalDevices is not None and \
-               self.totalDevices > self.memberDevices:
-                spares = self.totalDevices - self.memberDevices
-            elif self.totalDevices is None:
-                spares = self.memberDevices
-                self._totalDevices = self.memberDevices
-        return spares
-
-    def _setSpares(self, spares):
-        # FIXME: this is too simple to be right
-        if self.totalDevices > spares:
-            self.memberDevices = self.totalDevices - spares
-
-    spares = property(_getSpares, _setSpares)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        # We don't use self.status here because self.status requires a valid
-        # sysfs path to function correctly.
-        if os.path.exists(self.path):
-            md_node = mdraid.md_node_from_name(self.name)
-            self.sysfsPath = "/devices/virtual/block/%s" % md_node
-        else:
-            self.sysfsPath = ''
-
-    def _addDevice(self, device):
-        """ Add a new member device to the array.
-
-            XXX This is for use when probing devices, not for modification
-                of arrays.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not isinstance(device.format, self.formatClass):
-            raise ValueError("invalid device format for mdraid member")
-
-        if self.uuid and device.format.mdUuid != self.uuid:
-            raise ValueError("cannot add member with non-matching UUID")
-
-        if device in self.devices:
-            raise ValueError("device is already a member of this array")
-
-        # we added it, so now set up the relations
-        self.devices.append(device)
-        device.addChild()
-
-        device.setup()
-        udev_settle()
-
-        if self.spares > 0:
-            # mdadm doesn't like it when you try to incrementally add spares
-            return
-
-        try:
-            mdraid.mdadd(device.path)
-            # mdadd causes udev events
-            udev_settle()
-        except MDRaidError as e:
-            log.warning("failed to add member %s to md array %s: %s"
-                        % (device.path, self.path, e))
-
-        if self.status:
-            # we always probe since the device may not be set up when we want
-            # information about it
-            self._size = self.currentSize
-
-    def _removeDevice(self, device):
-        """ Remove a component device from the array.
-
-            XXX This is for use by clearpart, not for reconfiguration.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-
-        if device not in self.devices:
-            raise ValueError("cannot remove non-member device from array")
-
-        self.devices.remove(device)
-        device.removeChild()
-
-    def addMember(self, member):
-        if member in self.parents:
-            raise ValueError("member is already part of this array")
-
-        # for the time being we will not allow adding members to existing arrays
-        if self.exists:
-            raise DeviceError("cannot add member to existing array", self.name)
-
-        self.parents.append(member)
-        member.addChild()
-        self.memberDevices += 1
-
-    def removeMember(self, member):
-        self._removeDevice(member)
-        self.memberDevices -= 1
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        # check the status in sysfs
-        status = False
-        if not self.exists:
-            return status
-
-        state_file = "/sys/%s/md/array_state" % self.sysfsPath
-        if os.access(state_file, os.R_OK):
-            state = open(state_file).read().strip()
-            if state in ("clean", "active", "active-idle", "readonly", "read-auto"):
-                status = True
-            # mdcontainers have state inactive when started (clear if stopped)
-            if self.type == "mdcontainer" and state == "inactive":
-                status = True
-
-        return status
-
-    @property
-    def degraded(self):
-        """ Return True if the array is running in degraded mode. """
-        rc = False
-        degraded_file = "/sys/%s/md/degraded" % self.sysfsPath
-        if os.access(degraded_file, os.R_OK):
-            val = open(degraded_file).read().strip()
-            if val == "1":
-                rc = True
-
-        return rc
-
-    @property
-    def complete(self):
-        if self.type == "mdbiosraidarray":
-            members = len(self.parents[0].parents)
-        else:
-            members = len(self.parents)
-
-        return (self.memberDevices <= members) or not self.exists
-
-    @property
-    def devices(self):
-        """ Return a list of this array's member device instances. """
-        return self.parents
-
-    def _postSetup(self):
-        super(MDRaidArrayDevice, self)._postSetup()
-        self.updateSysfsPath()
-
-    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)
-        disks = []
-        for member in self.devices:
-            member.setup(orig=orig)
-            disks.append(member.path)
-
-        mdraid.mdactivate(self.path,
-                          members=disks,
-                          uuid=self.uuid)
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-        # we don't really care about the return value of _preTeardown here.
-        # see comment just above mddeactivate call
-        self._preTeardown(recursive=recursive)
-
-        # Since BIOS RAID sets (containers in mdraid terminology) never change
-        # there is no need to stop them and later restart them. Not stopping
-        # (and thus also not starting) them also works around bug 523334
-        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
-            return
-
-        # We don't really care what the array's state is. If the device
-        # file exists, we want to deactivate it. mdraid has too many
-        # states.
-        if self.exists and os.path.exists(self.path):
-            mdraid.mddeactivate(self.path)
-
-        self._postTeardown(recursive=recursive)
-
-    def preCommitFixup(self, *args, **kwargs):
-        """ Determine create parameters for this set """
-        mountpoints = kwargs.pop("mountpoints")
-        log_method_call(self, self.name, mountpoints)
-
-        if "/boot" in mountpoints:
-            bootmountpoint = "/boot"
-        else:
-            bootmountpoint = "/"
-
-        # If we are used to boot from we cannot use 1.1 metadata
-        if getattr(self.format, "mountpoint", None) == bootmountpoint or \
-           getattr(self.format, "mountpoint", None) == "/boot/efi" or \
-           self.format.type == "prepboot":
-            self.metadataVersion = "1.0"
-
-        # Bitmaps are not useful for swap and small partitions
-        if self.size < 1000 or self.format.type == "swap":
-            self.createBitmap = False
-
-    def _postCreate(self):
-        # this is critical since our status method requires a valid sysfs path
-        md_node = mdraid.md_node_from_name(self.name)
-        self.sysfsPath = "/devices/virtual/block/%s" % md_node
-        self.exists = True  # I think we can remove this.
-
-        StorageDevice._postCreate(self)
-
-        # update our uuid attribute with the new array's UUID
-        info = udev_get_block_device(self.sysfsPath)
-        self.uuid = udev_device_get_md_uuid(info)
-        for member in self.devices:
-            member.mdUuid = self.uuid
-
-    def _create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        disks = [disk.path for disk in self.devices]
-        spares = len(self.devices) - self.memberDevices
-        mdraid.mdcreate(self.path,
-                        self.level,
-                        disks,
-                        spares,
-                        metadataVer=self.metadataVersion,
-                        bitmap=self.createBitmap)
-
-    @property
-    def formatArgs(self):
-        formatArgs = []
-        if self.format.type == "ext2":
-            if self.level == mdraid.RAID5:
-                formatArgs = ['-R',
-                              'stride=%d' % ((self.memberDevices - 1) * 16)]
-            if self.level == mdraid.RAID4:
-                formatArgs = ['-R',
-                              'stride=%d' % ((self.memberDevices - 1) * 16)]
-            elif self.level == mdraid.RAID0:
-                formatArgs = ['-R',
-                              'stride=%d' % (self.memberDevices * 16)]
-
-    @property
-    def mediaPresent(self):
-        # Containers should not get any format handling done
-        # (the device node does not allow read / write calls)
-        if self.type == "mdcontainer":
-            return False
-        # BIOS RAID sets should show as present even when teared down
-        elif self.type == "mdbiosraidarray":
-            return True
-        elif flags.testing:
-            return True
-        else:
-            return self.partedDevice is not None
-
-    @property
-    def model(self):
-        return self.description
-
-    @property
-    def partitionable(self):
-        return self.type == "mdbiosraidarray"
-
-    @property
-    def isDisk(self):
-        return self.type == "mdbiosraidarray"
-
-    def dracutSetupArgs(self):
-        return set(["rd.md.uuid=%s" % self.uuid])
-
-class DMRaidArrayDevice(DMDevice):
-    """ A dmraid (device-mapper RAID) device """
-    _type = "dm-raid array"
-    _packages = ["dmraid"]
-    _partitionable = True
-    _isDisk = True
-
-    def __init__(self, name, raidSet=None, format=None,
-                 size=None, parents=None, sysfsPath=''):
-        """ Create a DMRaidArrayDevice instance.
-
-            Arguments:
-
-                name -- the dmraid name also the device node's basename
-
-            Keyword Arguments:
-
-                raidSet -- the RaidSet object from block
-                parents -- a list of the member devices
-                sysfsPath -- sysfs device path
-                size -- the device's size
-                format -- a DeviceFormat instance
-        """
-        if isinstance(parents, list):
-            for parent in parents:
-                if not parent.format or parent.format.type != "dmraidmember":
-                    raise ValueError("parent devices must contain dmraidmember format")
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath, exists=True)
-
-        self.formatClass = get_device_format_class("dmraidmember")
-        if not self.formatClass:
-            raise StorageError("cannot find class for 'dmraidmember'")
-
-        self._raidSet = raidSet
-
-    @property
-    def raidSet(self):
-        return self._raidSet
-
-    def _addDevice(self, device):
-        """ Add a new member device to the array.
-
-            XXX This is for use when probing devices, not for modification
-                of arrays.
-        """
-        log_method_call(self, self.name, device=device.name, status=self.status)
-
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not isinstance(device.format, self.formatClass):
-            raise ValueError("invalid device format for dmraid member")
-
-        if device in self.members:
-            raise ValueError("device is already a member of this array")
-
-        # we added it, so now set up the relations
-        self.devices.append(device)
-        device.addChild()
-
-    @property
-    def members(self):
-        return self.parents
-
-    @property
-    def devices(self):
-        """ Return a list of this array's member device instances. """
-        return self.parents
-
-    def deactivate(self):
-        """ Deactivate the raid set. """
-        log_method_call(self, self.name, status=self.status)
-        # This call already checks if the set is not active.
-        self._raidSet.deactivate()
-
-    def activate(self):
-        """ Activate the raid set. """
-        log_method_call(self, self.name, status=self.status)
-        # This call already checks if the set is active.
-        self._raidSet.activate(mknod=True)
-        udev_settle()
-
-    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)
-        self.activate()
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-        if not self._preTeardown(recursive=recursive):
-            return
-
-        log.debug("not tearing down dmraid device %s" % self.name)
-
-    @property
-    def description(self):
-        return "BIOS RAID set (%s)" % self._raidSet.rs.set_type
-
-    @property
-    def model(self):
-        return self.description
-
-    def dracutSetupArgs(self):
-        return set(["rd.dm.uuid=%s" % self.name])
-
-class MultipathDevice(DMDevice):
-    """ A multipath device """
-    _type = "dm-multipath"
-    _packages = ["device-mapper-multipath"]
-    _services = ["multipathd"]
-    _partitionable = True
-    _isDisk = True
-
-    def __init__(self, name, info, format=None, size=None,
-                 parents=None, sysfsPath=''):
-        """ Create a MultipathDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                info -- the udev info for this device
-
-            Keyword Arguments:
-
-                sysfsPath -- sysfs device path
-                size -- the device's size
-                format -- a DeviceFormat instance
-                parents -- a list of the backing devices (Device instances)
-        """
-
-        self._info = info
-        self.setupIdentity()
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath,
-                          exists=True)
-
-        self.config = {
-            'wwid' : self.identity,
-            'mode' : '0600',
-            'uid' : '0',
-            'gid' : '0',
-        }
-
-    def setupIdentity(self):
-        """ Adds identifying remarks to MultipathDevice object.
-        
-            May be overridden by a sub-class for e.g. RDAC handling.
-        """
-        self._identity = self._info.get("ID_SERIAL_RAW", self._info.get("ID_SERIAL_SHORT"))
-
-    @property
-    def identity(self):
-        """ Get identity set with setupIdentityFromInfo()
-        
-            May be overridden by a sub-class for e.g. RDAC handling.
-        """
-        if not hasattr(self, "_identity"):
-            raise RuntimeError, "setupIdentityFromInfo() has not been called."
-        return self._identity
-
-    @property
-    def wwid(self):
-        identity = self.identity
-        ret = []
-        while identity:
-            ret.append(identity[:2])
-            identity = identity[2:]
-        return ":".join(ret)
-
-    @property
-    def model(self):
-        if not self.parents:
-            return ""
-        return self.parents[0].model
-
-    @property
-    def vendor(self):
-        if not self.parents:
-            return ""
-        return self.parents[0].vendor
-
-    @property
-    def description(self):
-        return "WWID %s" % (self.wwid,)
-
-    def addParent(self, parent):
-        """ Add a parent device to the mpath. """
-        log_method_call(self, self.name, status=self.status)
-        if self.status:
-            self.teardown()
-            self.parents.append(parent)
-            self.setup()
-        else:
-            self.parents.append(parent)
-
-    def deactivate(self):
-        """ 
-        This is never called, included just for documentation.
-
-        If we called this during teardown(), we wouldn't be able to get parted
-        object because /dev/mapper/mpathX wouldn't exist.
-        """
-        if self.exists and os.path.exists(self.path):
-            #self.teardownPartitions()
-            #rc = util.run_program(["multipath", '-f', self.name])
-            #if rc:
-            #    raise MPathError("multipath deactivation failed for '%s'" %
-            #                    self.name)
-            bdev = block.getDevice(self.name)
-            devmap = block.getMap(major=bdev[0], minor=bdev[1])
-            if devmap.open_count:
-                return
-            try:
-                block.removeDeviceMap(devmap)
-            except Exception as e:
-                raise MPathError("failed to tear down multipath device %s: %s"
-                                % (self.name, e))
-
-    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)
-        udev_settle()
-        rc = util.run_program(["multipath", self.name])
-        if rc:
-            raise MPathError("multipath activation failed for '%s'" %
-                            self.name, hardware_fault=True)
-
-    def _postSetup(self):
-        StorageDevice._postSetup(self)
-        self.setupPartitions()
-        udev_settle()
-
-class NoDevice(StorageDevice):
-    """ A nodev device for nodev filesystems like tmpfs. """
-    _type = "nodev"
-
-    def __init__(self, format=None):
-        """ Create a NoDevice instance.
-
-            Arguments:
-
-            Keyword Arguments:
-
-                format -- a DeviceFormat instance
-        """
-        if format:
-            name = format.type
-        else:
-            name = "none"
-
-        StorageDevice.__init__(self, name, format=format, exists=True)
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return self.name
-
-    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)
-
-    def teardown(self, recursive=False):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-        # just make sure the format is unmounted
-        self._preTeardown(recursive=recursive)
-
-    def create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        self._preDestroy()
-
-
-class FileDevice(StorageDevice):
-    """ A file on a filesystem.
-
-        This exists because of swap files.
-    """
-    _type = "file"
-    _devDir = ""
-
-    def __init__(self, path, format=None, size=None,
-                 exists=False, parents=None):
-        """ Create a FileDevice instance.
-
-            Arguments:
-
-                path -- full path to the file
-
-            Keyword Arguments:
-
-                format -- a DeviceFormat instance
-                size -- the file size (units TBD)
-                parents -- a list of required devices (Device instances)
-                exists -- indicates whether this is an existing device
-        """
-        if not path.startswith("/"):
-            raise ValueError("FileDevice requires an absolute path")
-
-        StorageDevice.__init__(self, path, format=format, size=size,
-                               exists=exists, parents=parents)
-
-    @property
-    def fstabSpec(self):
-        return self.name
-
-    @property
-    def path(self):
-        root = ""
-        try:
-            status = self.parents[0].format.status
-        except (AttributeError, IndexError):
-            # either this device has no parents or something is wrong with
-            # the first one
-            status = (os.access(self.name, os.R_OK) and
-                      self.parents in ([], None))
-        else:
-            # this is the actual active mountpoint
-            root = self.parents[0].format._mountpoint
-            # trim the mountpoint down to the chroot since we already have
-            # the otherwise fully-qualified path
-            mountpoint = self.parents[0].format.mountpoint
-            while mountpoint.endswith("/"):
-                mountpoint = mountpoint[:-1]
-            if mountpoint:
-                root = root[:-len(mountpoint)]
-
-        return os.path.normpath("%s%s" % (root, self.name))
-
-    def _preSetup(self, orig=False):
-        if self.format and self.format.exists and not self.format.status:
-            self.format.device = self.path
-
-        return StorageDevice._preSetup(self, orig=orig)
-
-    def _preTeardown(self, recursive=None):
-        if self.format and self.format.exists and not self.format.status:
-            self.format.device = self.path
-
-        return StorageDevice._preTeardown(self, recursive=recursive)
-
-    def _create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        fd = os.open(self.path, os.O_WRONLY|os.O_CREAT|os.O_TRUNC)
-        buf = "\0" * 1024 * 1024
-        for n in range(self.size):
-            os.write(fd, buf)
-        os.close(fd)
-
-    def _destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        os.unlink(self.path)
-
-
-class SparseFileDevice(FileDevice):
-    """A sparse file on a filesystem.
-    This exists for sparse disk images."""
-    _type = "sparse file"
-    def _create(self):
-        """Create a sparse file."""
-        log_method_call(self, self.name, status=self.status)
-        fd = os.open(self.path, os.O_WRONLY|os.O_CREAT|os.O_TRUNC)
-        os.ftruncate(fd, 1024*1024*self.size)
-        os.close(fd)
-
-
-class DirectoryDevice(FileDevice):
-    """ A directory on a filesystem.
-
-        This exists because of bind mounts.
-    """
-    _type = "directory"
-
-    def _create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        util.makedirs(self.path)
-
-
-class LoopDevice(StorageDevice):
-    """ A loop device. """
-    _type = "loop"
-
-    def __init__(self, name=None, format=None, size=None, sysfsPath=None,
-                 exists=False, parents=None):
-        """ Create a LoopDevice instance.
-
-            Arguments:
-
-                name -- the device's name
-
-            Keyword Arguments:
-
-                format -- a DeviceFormat instance
-                size -- the device's size in MB
-                parents -- a list of required devices (Device instances)
-                exists -- indicates whether this is an existing device
-
-
-            Loop devices always exist.
-        """
-        if not parents:
-            raise ValueError("LoopDevice requires a backing device")
-
-        if not name:
-            # set up a temporary name until we've activated the loop device
-            name = "tmploop%d" % Device._id
-
-        StorageDevice.__init__(self, name, format=format, size=size,
-                               exists=True, parents=parents)
-
-    def updateName(self):
-        """ Update this device's name. """
-        if not self.slave.status:
-            # if the backing device is inactive, so are we
-            return self.name
-
-        if self.name.startswith("loop"):
-            # if our name is loopN we must already be active
-            return self.name
-
-        name = loop.get_loop_name(self.slave.path)
-        if name.startswith("loop"):
-            self._name = name
-
-        return self.name
-
-    @property
-    def status(self):
-        return (self.slave.status and
-                self.name.startswith("loop") and
-                loop.get_loop_name(self.slave.path) == self.name)
-
-    @property
-    def size(self):
-        return self.slave.size
-
-    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)
-        loop.loop_setup(self.slave.path)
-
-    def _postSetup(self):
-        StorageDevice._postSetup(self)
-        self.updateName()
-        self.updateSysfsPath()
-
-    def _teardown(self, recursive=False):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-        loop.loop_teardown(self.path)
-
-    def _postTeardown(self, recursive=False):
-        StorageDevice._postTeardown(self, recursive=recursive)
-        self._name = "tmploop%d" % self.id
-        self.sysfsPath = ''
-
-    @property
-    def slave(self):
-        return self.parents[0]
-
-
-class iScsiDiskDevice(DiskDevice, NetworkStorageDevice):
-    """ An iSCSI disk. """
-    _type = "iscsi"
-    _packages = ["iscsi-initiator-utils", "dracut-network"]
-
-    def __init__(self, device, **kwargs):
-        self.node = kwargs.pop("node")
-        self.ibft = kwargs.pop("ibft")
-        self.nic = kwargs.pop("nic")
-        self.initiator = kwargs.pop("initiator")
-
-        if self.node is None:
-            # qla4xxx partial offload
-            name = kwargs.pop("fw_name")
-            address = kwargs.pop("fw_address")
-            port = kwargs.pop("fw_port")
-            DiskDevice.__init__(self, device, **kwargs)
-            NetworkStorageDevice.__init__(self,
-                                          host_address=address,
-                                          nic=self.nic)
-            log.debug("created new iscsi disk %s %s:%s using fw initiator %s"
-                      % (name, address, port, self.initiator))
-        else:
-            DiskDevice.__init__(self, device, **kwargs)
-            NetworkStorageDevice.__init__(self, host_address=self.node.address,
-                                          nic=self.nic)
-            log.debug("created new iscsi disk %s %s:%d via %s:%s" % (self.node.name,
-                                                                  self.node.address,
-                                                                  self.node.port,
-                                                                  self.node.iface,
-                                                                  self.nic))
-
-    def dracutSetupArgs(self):
-        if self.ibft:
-            return set(["iscsi_firmware"])
-
-        # qla4xxx partial offload
-        if self.node is None:
-            return set()
-
-        address = self.node.address
-        # surround ipv6 addresses with []
-        if ":" in address:
-            address = "[%s]" % address
-
-        netroot="netroot=iscsi:"
-        auth = self.node.getAuth()
-        if auth:
-            netroot += "%s:%s" % (auth.username, auth.password)
-            if len(auth.reverse_username) or len(auth.reverse_password):
-                netroot += ":%s:%s" % (auth.reverse_username,
-                                       auth.reverse_password)
-
-        iface_spec = ""
-        if self.nic != "default":
-            iface_spec = ":%s:%s" % (self.node.iface, self.nic)
-        netroot += "@%s::%d%s::%s" % (address,
-                                      self.node.port,
-                                      iface_spec,
-                                      self.node.name)
-
-        initiator = "iscsi_initiator=%s" % self.initiator
-
-        return set([netroot, initiator])
-
-class FcoeDiskDevice(DiskDevice, NetworkStorageDevice):
-    """ An FCoE disk. """
-    _type = "fcoe"
-    _packages = ["fcoe-utils", "dracut-network"]
-
-    def __init__(self, device, **kwargs):
-        self.nic = kwargs.pop("nic")
-        self.identifier = kwargs.pop("identifier")
-        DiskDevice.__init__(self, device, **kwargs)
-        NetworkStorageDevice.__init__(self, nic=self.nic)
-        log.debug("created new fcoe disk %s (%s) @ %s" %
-                  (device, self.identifier, self.nic))
-
-    def dracutSetupArgs(self):
-        dcb = True
-
-        from .fcoe import fcoe
-        for nic, dcb, auto_vlan in fcoe().nics:
-            if nic == self.nic:
-                break
-
-        if dcb:
-            dcbOpt = "dcb"
-        else:
-            dcbOpt = "nodcb"
-
-        return set(["fcoe=edd:%s" % dcbOpt])
-
-
-class OpticalDevice(StorageDevice):
-    """ An optical drive, eg: cdrom, dvd+r, &c.
-
-        XXX Is this useful?
-    """
-    _type = "cdrom"
-
-    def __init__(self, name, major=None, minor=None, exists=False,
-                 format=None, parents=None, sysfsPath='', vendor="",
-                 model=""):
-        StorageDevice.__init__(self, name, format=format,
-                               major=major, minor=minor, exists=True,
-                               parents=parents, sysfsPath=sysfsPath,
-                               vendor=vendor, model=model)
-
-    @property
-    def mediaPresent(self):
-        """ Return a boolean indicating whether or not the device contains
-            media.
-        """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        try:
-            fd = os.open(self.path, os.O_RDONLY)
-        except OSError as e:
-            # errno 123 = No medium found
-            if e.errno == 123:
-                return False
-            else:
-                return True
-        else:
-            os.close(fd)
-            return True
-
-    def eject(self):
-        """ Eject the drawer. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        #try to umount and close device before ejecting
-        self.teardown()
-
-        try:
-            util.run_program(["eject", self.name]) 
-        except OSError as e:
-            log.warning("error ejecting cdrom %s: %s" % (self.name, e))
-
-
-class ZFCPDiskDevice(DiskDevice):
-    """ A mainframe ZFCP disk. """
-    _type = "zfcp"
-
-    def __init__(self, device, **kwargs):
-        self.hba_id = kwargs.pop("hba_id")
-        self.wwpn = kwargs.pop("wwpn")
-        self.fcp_lun = kwargs.pop("fcp_lun")
-        DiskDevice.__init__(self, device, **kwargs)
-
-    def __repr__(self):
-        s = DiskDevice.__repr__(self)
-        s += ("  hba_id = %(hba_id)s  wwpn = %(wwpn)s  fcp_lun = %(fcp_lun)s" %
-              {"hba_id": self.hba_id,
-               "wwpn": self.wwpn,
-               "fcp_lun": self.fcp_lun})
-        return s
-
-    @property
-    def description(self):
-        return "FCP device %(device)s with WWPN %(wwpn)s and LUN %(lun)s" \
-               % {'device': self.hba_id,
-                  'wwpn': self.wwpn,
-                  'lun': self.fcp_lun}
-
-    def dracutSetupArgs(self):
-        return set(["rd.zfcp=%s,%s,%s" % (self.hba_id, self.wwpn, self.fcp_lun,)])
-
-class DASDDevice(DiskDevice):
-    """ A mainframe DASD. """
-    _type = "dasd"
-
-    def __init__(self, device, **kwargs):
-        self.busid = kwargs.pop('busid')
-        self.opts = kwargs.pop('opts')
-        self.dasd = kwargs.pop('dasd')
-        DiskDevice.__init__(self, device, **kwargs)
-
-        if self.dasd:
-            self.dasd.addDASD(self)
-
-    @property
-    def description(self):
-        return "DASD device %s" % self.busid
-
-    def getOpts(self):
-        return ["%s=%s" % (k, v) for k, v in self.opts.items() if v == '1']
-
-    def dracutSetupArgs(self):
-        conf = "/etc/dasd.conf"
-        line = None
-        if os.path.isfile(conf):
-            f = open(conf)
-            # grab the first line that starts with our busID
-            line = [line for line in f.readlines()
-                    if line.startswith(self.busid)][:1]
-            f.close()
-
-        # See if we got a line.  If not, grab our getOpts
-        if not line:
-            line = self.busid
-            for devopt in self.getOpts():
-                line += " %s" % devopt
-
-        # Create a translation mapping from dasd.conf format to module format
-        translate = {'use_diag': 'diag',
-                     'readonly': 'ro',
-                     'erplog': 'erplog',
-                     'failfast': 'failfast'}
-
-        # this is a really awkward way of determining if the
-        # feature found is actually desired (1, not 0), plus
-        # translating that feature into the actual kernel module
-        # value
-        opts = []
-        parts = line.split()
-        for chunk in parts[1:]:
-            try:
-                feat, val = chunk.split('=')
-                if int(val):
-                    opts.append(translate[feat])
-            except:
-                # If we don't know what the feature is (feat not in translate
-                # or if we get a val that doesn't cleanly convert to an int
-                # we can't do anything with it.
-                log.warning("failed to parse dasd feature %s" % chunk)
-
-        if opts:
-            return set(["rd.dasd=%s(%s)" % (self.busid,
-                                            ":".join(opts))])
-        else:
-            return set(["rd.dasd=%s" % self.busid])
-
-class NFSDevice(StorageDevice, NetworkStorageDevice):
-    """ An NFS device """
-    _type = "nfs"
-    _packages = ["dracut-network"]
-
-    def __init__(self, device, format=None, parents=None):
-        # we could make host/ip, path, &c but will anything use it?
-        StorageDevice.__init__(self, device, format=format, parents=parents)
-        NetworkStorageDevice.__init__(self, device.split(":")[0])
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return self.name
-
-    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)
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status,
-                        controllable=self.controllable)
-
-    def create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        self._preCreate()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-
-
-class BTRFSDevice(StorageDevice):
-    """ Base class for BTRFS volume and sub-volume devices. """
-    _type = "btrfs"
-    _packages = ["btrfs-progs"]
-
-    def __init__(self, *args, **kwargs):
-        """ Passing None or no name means auto-generate one like btrfs.%d """
-        if not args or not args[0]:
-            args = ("btrfs.%d" % Device._id,)
-
-        self.req_size = kwargs.pop("size", None)
-        super(BTRFSDevice, self).__init__(*args, **kwargs)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        self.parents[0].updateSysfsPath()
-        self.sysfsPath = self.parents[0].sysfsPath
-        log.debug("%s sysfsPath set to %s" % (self.name, self.sysfsPath))
-
-    def _postCreate(self):
-        super(BTRFSDevice, self)._postCreate()
-        self.format.exists = True
-        self.format.device = self.path
-
-    def _preDestroy(self):
-        """ Preparation and precondition checking for device destruction. """
-        super(BTRFSDevice, self)._preDestroy()
-        self.setupParents(orig=True)
-
-    def _getSize(self):
-        size = sum([d.size for d in self.parents])
-        return size
-
-    def _setSize(self, size):
-        raise RuntimeError("cannot directly set size of btrfs volume")
-
-    @property
-    def status(self):
-        return not any([not d.status for d in self.parents])
-
-    @property
-    def _temp_dir_prefix(self):
-        return "btrfs-tmp.%s" % self.id
-
-    def _do_temp_mount(self, orig=False):
-        if self.format.status or not self.exists:
-            return
-
-        tmpdir = tempfile.mkdtemp(prefix=self._temp_dir_prefix)
-        if orig:
-            fmt = self.originalFormat
-        else:
-            fmt = self.format
-
-        fmt.mount(mountpoint=tmpdir)
-
-    def _undo_temp_mount(self):
-        if getattr(self.format, "_mountpoint", None):
-            fmt = self.format
-        elif getattr(self.originalFormat, "_mountpoint", None):
-            fmt = self.originalFormat
-        else:
-            return
-
-        mountpoint = fmt._mountpoint
-
-        if os.path.basename(mountpoint).startswith(self._temp_dir_prefix):
-            fmt.unmount()
-            os.rmdir(mountpoint)
-
-    @property
-    def path(self):
-        return self.parents[0].path
-
-
-class BTRFSVolumeDevice(BTRFSDevice):
-    _type = "btrfs volume"
-
-    def __init__(self, *args, **kwargs):
-        self.dataLevel = kwargs.pop("dataLevel", None)
-        self.metaDataLevel = kwargs.pop("metaDataLevel", None)
-
-        super(BTRFSVolumeDevice, self).__init__(*args, **kwargs)
-
-        self.subvolumes = []
-
-        for parent in self.parents:
-            if parent.format.type != "btrfs":
-                raise ValueError("member device %s is not BTRFS" % parent.name)
-
-            if parent.format.exists and self.exists and \
-               parent.format.volUUID != self.uuid:
-                raise ValueError("BTRFS member device %s UUID %s does not "
-                                 "match volume UUID %s" % (parent.name,
-                                 parent.format.volUUID, self.uuid))
-
-        if self.parents and not self.format.type:
-            label = getattr(self.parents[0].format, "label", None)
-            self.format = getFormat("btrfs",
-                                    exists=self.exists,
-                                    label=label,
-                                    volUUID=self.uuid,
-                                    device=self.path)
-            self.originalFormat = copy.copy(self.format)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        super(BTRFSVolumeDevice, self)._setFormat(format)
-        self._name = "btrfs.%d" % self.id
-        label = getattr(self.format, "label", None)
-        if label:
-            self._name = label
-
-    def _getSize(self):
-        size = sum([d.size for d in self.parents])
-        if self.dataLevel in ("raid1", "raid10"):
-            size /= len(self.parents)
-
-        return size
-
-    def _addDevice(self, device):
-        """ Add a new device to this volume.
-
-            XXX This is for use by device probing routines and is not
-                intended for modification of the volume.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        if not self.exists:
-            raise DeviceError("device does not exist", self.name)
-
-        if device.format.type != "btrfs":
-            raise ValueError("addDevice requires a btrfs device as sole arg")
-
-        if device.format.volUUID != self.uuid:
-            raise ValueError("device UUID does not match the volume UUID")
-
-        if device in self.parents:
-            raise ValueError("device is already a member of this volume")
-
-        self.parents.append(device)
-        device.addChild()
-
-    def _removeDevice(self, device):
-        """ Remove a device from the volume.
-
-            This is for cases like clearing of preexisting partitions.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        try:
-            self.parents.remove(device)
-        except ValueError:
-            raise ValueError("cannot remove non-member device from volume")
-
-        device.removeChild()
-
-    def addMember(self, member):
-        if member in self.parents:
-            raise ValueError("member is already part of this volume")
-
-        # for the time being we will not allow adding members to existing vols
-        if self.exists:
-            raise DeviceError("cannot add member to existing volume", self.name)
-
-        self.parents.append(member)
-        member.addChild()
-
-    def removeMember(self, member):
-        if member not in self.parents:
-            raise ValueError("member is not part of this volume")
-
-        if self.exists:
-            raise DeviceError("cannot remove member from an existing volume")
-
-        self.parents.remove(member)
-        member.removeChild()
-
-    def _addSubVolume(self, vol):
-        if vol.name in [v.name for v in self.subvolumes]:
-            raise ValueError("subvolume %s already exists" % vol.name)
-
-        self.subvolumes.append(vol)
-
-    def _removeSubVolume(self, name):
-        if name not in [v.name for v in self.subvolumes]:
-            raise ValueError("cannot remove non-existent subvolume %s" % name)
-
-        names = [v.name for v in self.subvolumes]
-        self.subvolumes.pop(names.index(name))
-
-    def listSubVolumes(self):
-        subvols = []
-        self.setup(orig=True)
-        try:
-            self._do_temp_mount(orig=True)
-        except FSError as e:
-            log.debug("btrfs temp mount failed: %s" % e)
-            return subvols
-
-        try:
-            subvols = btrfs.list_subvolumes(self.originalFormat._mountpoint)
-        except BTRFSError as e:
-            log.debug("failed to list subvolumes: %s" % e)
-        finally:
-            self._undo_temp_mount()
-
-        return subvols
-
-    def createSubVolumes(self):
-        self._do_temp_mount()
-        for name, subvol in self.subvolumes:
-            if subvol.exists:
-                continue
-            subvol.create(mountpoint=self._temp_dir_prefix)
-        self._undo_temp_mount()
-
-    def removeSubVolume(self, name):
-        raise NotImplementedError()
-
-    def _create(self):
-        log_method_call(self, self.name, status=self.status)
-        btrfs.create_volume(devices=[d.path for d in self.parents],
-                            label=self.format.label,
-                            data=self.dataLevel,
-                            metadata=self.metaDataLevel)
-
-    def _destroy(self):
-        log_method_call(self, self.name, status=self.status)
-        for device in self.parents:
-            device.setup(orig=True)
-            DeviceFormat(device=device.path, exists=True).destroy()
-
-class BTRFSSubVolumeDevice(BTRFSDevice):
-    """ A btrfs subvolume pseudo-device. """
-    _type = "btrfs subvolume"
-
-    def __init__(self, *args, **kwargs):
-        self.vol_id = kwargs.pop("vol_id", None)
-        super(BTRFSSubVolumeDevice, self).__init__(*args, **kwargs)
-
-        self.volume._addSubVolume(self)
-
-    @property
-    def volume(self):
-        return self.parents[0]
-
-    def setupParents(self, orig=False):
-        """ Run setup method of all parent devices. """
-        log_method_call(self, name=self.name, orig=orig, kids=self.kids)
-        self.volume.setup(orig=orig)
-
-    def _create(self):
-        log_method_call(self, self.name, status=self.status)
-        self.volume._do_temp_mount()
-        mountpoint = self.volume.format._mountpoint
-        if not mountpoint:
-            raise RuntimeError("btrfs subvol create requires mounted volume")
-
-        btrfs.create_subvolume(mountpoint, self.name)
-        self.volume._undo_temp_mount()
-
-    def _destroy(self):
-        log_method_call(self, self.name, status=self.status)
-        self.volume._do_temp_mount(orig=True)
-        mountpoint = self.volume.originalFormat._mountpoint
-        if not mountpoint:
-            raise RuntimeError("btrfs subvol destroy requires mounted volume")
-        btrfs.delete_subvolume(mountpoint, self.name)
-        self.volume._undo_temp_mount()
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py
deleted file mode 100644
index f0d49f7..0000000
--- a/pyanaconda/storage/devicetree.py
+++ /dev/null
@@ -1,2205 +0,0 @@
-# devicetree.py
-# Device management for anaconda's storage configuration module.
-#
-# Copyright (C) 2009, 2010, 2011  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-import stat
-import block
-import re
-import shutil
-import pprint
-import copy
-
-from errors import *
-from devices import *
-from deviceaction import *
-from pykickstart.constants import *
-import formats
-import devicelibs.mdraid
-import devicelibs.dm
-import devicelibs.lvm
-import devicelibs.mpath
-import devicelibs.loop
-import devicelibs.edd
-from udev import *
-import util
-from platform import platform
-import tsort
-from flags import flags
-from storage_log import log_method_call, log_method_return
-import parted
-import _ped
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-class DeviceTree(object):
-    """ A quasi-tree that represents the devices in the system.
-
-        The tree contains a list of device instances, which does not
-        necessarily reflect the actual state of the system's devices.
-        DeviceActions are used to perform modifications to the tree,
-        except when initially populating the tree.
-
-        DeviceAction instances are registered, possibly causing the
-        addition or removal of Device instances to/from the tree. The
-        DeviceActions are all reversible up to the time their execute
-        method has been called.
-
-        Only one action of any given type/object pair should exist for
-        any given device at any given time.
-
-        DeviceAction instances can only be registered for leaf devices,
-        except for resize actions.
-    """
-
-    def __init__(self, conf=None, passphrase=None, luksDict=None,
-                 iscsi=None, dasd=None):
-        self.reset(conf, passphrase, luksDict, iscsi, dasd)
-
-    def reset(self, conf=None, passphrase=None, luksDict=None,
-              iscsi=None, dasd=None):
-        # internal data members
-        self._devices = []
-        self._actions = []
-
-        # a list of all device names we encounter
-        self.names = []
-
-        self._hidden = []
-
-        # indicates whether or not the tree has been fully populated
-        self.populated = False
-
-        self.exclusiveDisks = getattr(conf, "exclusiveDisks", [])
-        self.iscsi = iscsi
-        self.dasd = dasd
-        self.mpathFriendlyNames = getattr(conf, "mpathFriendlyNames", True)
-
-        self.diskImages = {}
-        images = getattr(conf, "diskImages", {})
-        if images:
-            # this will overwrite self.exclusiveDisks
-            self.setDiskImages(images)
-
-        # protected device specs as provided by the user
-        self.protectedDevSpecs = getattr(conf, "protectedDevSpecs", [])
-        self.liveBackingDevice = None
-
-        # names of protected devices at the time of tree population
-        self.protectedDevNames = []
-
-        self.unusedRaidMembers = []
-
-        self.__multipaths = {}
-        self.__multipathConfigWriter = devicelibs.mpath.MultipathConfigWriter()
-
-        self.__passphrases = []
-        if passphrase:
-            self.__passphrases.append(passphrase)
-
-        self.__luksDevs = {}
-        if luksDict and isinstance(luksDict, dict):
-            self.__luksDevs = luksDict
-            self.__passphrases.extend([p for p in luksDict.values() if p])
-
-        self._ignoredDisks = []
-        for disk in getattr(conf, "ignoredDisks", []):
-            self.addIgnoredDisk(disk)
-        devicelibs.lvm.lvm_cc_resetFilter()
-
-        self._cleanup = False
-
-    def setDiskImages(self, images):
-        """ Set the disk images and reflect them in exclusiveDisks. """
-        self.diskImages = images
-        # disk image files are automatically exclusive
-        self.exclusiveDisks = self.diskImages.keys()
-
-    def addIgnoredDisk(self, disk):
-        self._ignoredDisks.append(disk)
-        devicelibs.lvm.lvm_cc_addFilterRejectRegexp(disk)
-
-    def pruneActions(self):
-        """ Remove redundant/obsolete actions from the action list. """
-        for action in reversed(self._actions[:]):
-            if action not in self._actions:
-                log.debug("action %d already pruned" % action.id)
-                continue
-
-            for obsolete in self._actions[:]:
-                if action.obsoletes(obsolete):
-                    log.info("removing obsolete action %d (%d)"
-                             % (obsolete.id, action.id))
-                    self._actions.remove(obsolete)
-
-    def sortActions(self):
-        """ Sort actions based on dependencies. """
-        if not self._actions:
-            return
-
-        edges = []
-
-        # collect all ordering requirements for the actions
-        for action in self._actions:
-            action_idx = self._actions.index(action)
-            children = []
-            for _action in self._actions:
-                if _action == action:
-                    continue
-
-                # create edges based on both action type and dependencies.
-                if action.type > _action.type or _action.requires(action):
-                    children.append(_action)
-
-            for child in children:
-                child_idx = self._actions.index(child)
-                edges.append((action_idx, child_idx))
-
-        # create a graph reflecting the ordering information we have
-        graph = tsort.create_graph(range(len(self._actions)), edges)
-
-        # perform a topological sort based on the graph's contents
-        order = tsort.tsort(graph)
-
-        # now replace self._actions with a sorted version of the same list
-        actions = []
-        for idx in order:
-            actions.append(self._actions[idx])
-        self._actions = actions
-
-    def processActions(self, dryRun=None):
-        """ Execute all registered actions. """
-        log.info("resetting parted disks...")
-        for device in self.devices:
-            if device.partitioned:
-                device.format.resetPartedDisk()
-                if device.originalFormat.type == "disklabel" and \
-                   device.originalFormat != device.format:
-                    device.originalFormat.resetPartedDisk()
-
-        # Call preCommitFixup on all devices
-        mpoints = [getattr(d.format, 'mountpoint', "") for d in self.devices]
-        for device in self.devices:
-            device.preCommitFixup(mountpoints=mpoints)
-
-        # Also call preCommitFixup on any devices we're going to
-        # destroy (these are already removed from the tree)
-        for action in self._actions:
-            if isinstance(action, ActionDestroyDevice):
-                action.device.preCommitFixup(mountpoints=mpoints)
-
-        # setup actions to create any extended partitions we added
-        #
-        # XXX At this point there can be duplicate partition paths in the
-        #     tree (eg: non-existent sda6 and previous sda6 that will become
-        #     sda5 in the course of partitioning), so we access the list
-        #     directly here.
-        for device in self._devices:
-            if isinstance(device, PartitionDevice) and \
-               device.isExtended and not device.exists:
-                # don't properly register the action since the device is
-                # already in the tree
-                self._actions.append(ActionCreateDevice(device))
-
-        for action in self._actions:
-            log.debug("action: %s" % action)
-
-        log.info("pruning action queue...")
-        self.pruneActions()
-
-        log.info("sorting actions...")
-        self.sortActions()
-        for action in self._actions:
-            log.debug("action: %s" % action)
-
-        for action in self._actions:
-            log.info("executing action: %s" % action)
-            if not dryRun:
-                try:
-                    action.execute()
-                except DiskLabelCommitError:
-                    # it's likely that a previous format destroy action
-                    # triggered setup of an lvm or md device.
-                    self.teardownAll()
-                    action.execute()
-
-                udev_settle()
-                for device in self._devices:
-                    # make sure we catch any renumbering parted does
-                    if device.exists and isinstance(device, PartitionDevice):
-                        device.updateName()
-                        device.format.device = device.path
-
-    def _addDevice(self, newdev):
-        """ Add a device to the tree.
-
-            Raise ValueError if the device's identifier is already
-            in the list.
-        """
-        if newdev.uuid and newdev.uuid in [d.uuid for d in self._devices] and \
-           not isinstance(newdev, NoDevice):
-            raise ValueError("device is already in tree")
-
-        # make sure this device's parent devices are in the tree already
-        for parent in newdev.parents:
-            if parent not in self._devices:
-                raise DeviceTreeError("parent device not in tree")
-
-        self._devices.append(newdev)
-
-        # don't include "req%d" partition names
-        if ((newdev.type != "partition" or
-             not newdev.name.startswith("req")) and
-            newdev.type != "btrfs volume" and
-            newdev.name not in self.names):
-            self.names.append(newdev.name)
-        log.info("added %s %s (id %d) to device tree" % (newdev.type,
-                                                          newdev.name,
-                                                          newdev.id))
-
-    def _removeDevice(self, dev, force=None, moddisk=True):
-        """ Remove a device from the tree.
-
-            Only leaves may be removed.
-        """
-        if dev not in self._devices:
-            raise ValueError("Device '%s' not in tree" % dev.name)
-
-        if not dev.isleaf and not force:
-            log.debug("%s has %d kids" % (dev.name, dev.kids))
-            raise ValueError("Cannot remove non-leaf device '%s'" % dev.name)
-
-        # if this is a partition we need to remove it from the parted.Disk
-        if moddisk and isinstance(dev, PartitionDevice) and \
-                dev.disk is not None:
-            # if this partition hasn't been allocated it could not have
-            # a disk attribute
-            if dev.partedPartition.type == parted.PARTITION_EXTENDED and \
-                    len(dev.disk.format.logicalPartitions) > 0:
-                raise ValueError("Cannot remove extended partition %s.  "
-                        "Logical partitions present." % dev.name)
-
-            dev.disk.format.removePartition(dev.partedPartition)
-
-            # adjust all other PartitionDevice instances belonging to the
-            # same disk so the device name matches the potentially altered
-            # name of the parted.Partition
-            for device in self._devices:
-                if isinstance(device, PartitionDevice) and \
-                   device.disk == dev.disk:
-                    device.updateName()
-        elif hasattr(dev, "vg"):
-            dev.vg._removeLogVol(dev)
-        elif hasattr(dev, "volume"):
-            dev.volume._removeSubVolume(dev.name)
-
-        self._devices.remove(dev)
-        if dev.name in self.names and getattr(dev, "complete", True):
-            self.names.remove(dev.name)
-        log.info("removed %s %s (id %d) from device tree" % (dev.type,
-                                                              dev.name,
-                                                              dev.id))
-
-        for parent in dev.parents:
-            # Will this cause issues with garbage collection?
-            #   Do we care about garbage collection? At all?
-            parent.removeChild()
-
-    def registerAction(self, action):
-        """ Register an action to be performed at a later time.
-
-            Modifications to the Device instance are handled before we
-            get here.
-        """
-        if not (action.isCreate and action.isDevice) and \
-           action.device not in self._devices:
-            raise DeviceTreeError("device is not in the tree")
-        elif (action.isCreate and action.isDevice):
-            if action.device in self._devices:
-                raise DeviceTreeError("device is already in the tree")
-
-        if action.isCreate and action.isDevice:
-            self._addDevice(action.device)
-        elif action.isDestroy and action.isDevice:
-            self._removeDevice(action.device)
-        elif action.isCreate and action.isFormat:
-            if isinstance(action.device.format, formats.fs.FS) and \
-               action.device.format.mountpoint in self.filesystems:
-                raise DeviceTreeError("mountpoint already in use")
-
-        log.info("registered action: %s" % action)
-        self._actions.append(action)
-
-    def cancelAction(self, action):
-        """ Cancel a registered action.
-
-            This will unregister the action and do any required
-            modifications to the device list.
-
-            Actions all operate on a Device, so we can use the devices
-            to determine dependencies.
-        """
-        if action.isCreate and action.isDevice:
-            # remove the device from the tree
-            self._removeDevice(action.device)
-        elif action.isDestroy and action.isDevice:
-            # add the device back into the tree
-            self._addDevice(action.device)
-        elif action.isFormat and \
-             (action.isCreate or action.isResize):
-            action.cancel()
-
-        self._actions.remove(action)
-
-    def findActions(self, device=None, type=None, object=None, path=None,
-                    devid=None):
-        """ Find all actions that match all specified parameters.
-
-            Keyword arguments:
-
-                device -- device to match (Device, or None to match any)
-                type -- action type to match (string, or None to match any)
-                object -- operand type to match (string, or None to match any)
-                path -- device path to match (string, or None to match any)
-
-        """
-        if device is None and type is None and object is None and \
-           path is None and devid is None:
-            return self._actions[:]
-
-        # convert the string arguments to the types used in actions
-        _type = action_type_from_string(type)
-        _object = action_object_from_string(object)
-
-        actions = []
-        for action in self._actions:
-            if device is not None and action.device != device:
-                continue
-
-            if _type is not None and action.type != _type:
-                continue
-
-            if _object is not None and action.obj != _object:
-                continue
-
-            if path is not None and action.device.path != path:
-                continue
-
-            if devid is not None and action.device.id != devid:
-                continue
-                
-            actions.append(action)
-
-        return actions
-
-    def getDependentDevices(self, dep):
-        """ Return a list of devices that depend on dep.
-
-            The list includes both direct and indirect dependents.
-        """
-        dependents = []
-
-        # special handling for extended partitions since the logical
-        # partitions and their deps effectively depend on the extended
-        logicals = []
-        if isinstance(dep, PartitionDevice) and dep.partType and \
-           dep.isExtended:
-            # collect all of the logicals on the same disk
-            for part in self.getDevicesByInstance(PartitionDevice):
-                if part.partType and part.isLogical and part.disk == dep.disk:
-                    logicals.append(part)
-
-        incomplete = [d for d in self._devices
-                            if not getattr(d, "complete", True)]
-        for device in self.devices + incomplete:
-            if device.dependsOn(dep):
-                dependents.append(device)
-            else:
-                for logical in logicals:
-                    if device.dependsOn(logical):
-                        dependents.append(device)
-                        break
-
-        return dependents
-
-    def isIgnored(self, info):
-        """ Return True if info is a device we should ignore.
-
-            Arguments:
-
-                info -- a dict representing a udev db entry
-
-            TODO:
-
-                - filtering of SAN/FC devices
-                - filtering by driver?
-
-        """
-        sysfs_path = udev_device_get_sysfs_path(info)
-        name = udev_device_get_name(info)
-        if not sysfs_path:
-            return None
-
-        if name in self._ignoredDisks:
-            log.debug("device '%s' in ignoredDisks" % name)
-            return True
-
-        # Special handling for mdraid external metadata sets (mdraid BIOSRAID):
-        # 1) The containers are intermediate devices which will never be
-        # in exclusiveDisks
-        # 2) Sets get added to exclusive disks with their dmraid set name by
-        # the filter ui.  Note that making the ui use md names instead is not
-        # possible as the md names are simpy md# and we cannot predict the #
-        if udev_device_is_md(info) and \
-           udev_device_get_md_level(info) == "container":
-            return False
-
-        if udev_device_get_md_container(info) and \
-               udev_device_is_md(info) and \
-               udev_device_get_md_name(info):
-            md_name = udev_device_get_md_name(info)
-            # mdadm may have appended _<digit>+ if the current hostname
-            # does not match the one in the array metadata
-            alt_name = re.sub("_\d+$", "", md_name)
-            raw_pattern = "isw_[a-z]*_%s"
-            for i in range(0, len(self.exclusiveDisks)):
-                if re.match(raw_pattern % md_name, self.exclusiveDisks[i]) or \
-                   re.match(raw_pattern % alt_name, self.exclusiveDisks[i]):
-                    self.exclusiveDisks[i] = name
-                    return False
-
-        # never ignore mapped disk images. if you don't want to use them,
-        # don't specify them in the first place
-        if udev_device_is_dm_anaconda(info) or udev_device_is_dm_livecd(info):
-            return False
-
-        # Ignore loop and ram devices, we normally already skip these in
-        # udev.py: enumerate_block_devices(), but we can still end up trying
-        # to add them to the tree when they are slaves of other devices, this
-        # happens for example with the livecd
-        if name.startswith("ram"):
-            return True
-
-        if name.startswith("loop"):
-            # ignore loop devices unless they're backed by a file
-            return (not devicelibs.loop.get_backing_file(name))
-
-        # We want exclusiveDisks to operate on anything that could be
-        # considered a directly usable disk, ie: fwraid array, mpath, or disk.
-        #
-        # Unfortunately, since so many things are represented as disks by
-        # udev/sysfs, we have to define what is a disk in terms of what is
-        # not a disk.
-        if udev_device_is_disk(info) and \
-           not udev_device_is_dm_partition(info) and \
-           not udev_device_is_dm_lvm(info) and \
-           not udev_device_is_dm_crypt(info) and \
-           not (udev_device_is_md(info) and
-                not udev_device_get_md_container(info)):
-            if self.exclusiveDisks and name not in self.exclusiveDisks:
-                log.debug("device '%s' not in exclusiveDisks" % name)
-                self.addIgnoredDisk(name)
-                return True
-
-        # Ignore any readonly disks
-        if (udev_device_is_disk(info) and not
-            (udev_device_is_cdrom(info) or
-             udev_device_is_partition(info) or
-             udev_device_is_dm_partition(info) or
-             udev_device_is_dm_lvm(info) or
-             udev_device_is_dm_crypt(info) or
-             (udev_device_is_md(info) and not
-              udev_device_get_md_container(info)))):
-            if util.get_sysfs_attr(info["sysfs_path"], 'ro') == '1':
-                log.debug("Ignoring read only device %s" % name)
-                self.addIgnoredDisk(name)
-                return True
-
-        # FIXME: check for virtual devices whose slaves are on the ignore list
-
-    def addUdevLVDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        # initiate detection of all PVs and hope that it leads to us having
-        # the VG and LVs in the tree
-        for pv_name in os.listdir("/sys" + sysfs_path + "/slaves"):
-            link = os.readlink("/sys" + sysfs_path + "/slaves/" + pv_name)
-            pv_sysfs_path = os.path.normpath(sysfs_path + '/slaves/' + link)
-            pv_info = udev_get_block_device(pv_sysfs_path)
-            self.addUdevDevice(pv_info)
-
-        vg_name = udev_device_get_lv_vg_name(info)
-        device = self.getDeviceByName(vg_name)
-        if not device:
-            log.error("failed to find vg '%s' after scanning pvs" % vg_name)
-
-        # Don't return the device like we do in the other addUdevFooDevice
-        # methods. The device we have here is a vg, not an lv.
-
-    def addUdevDMDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        for dmdev in self.devices:
-            if not isinstance(dmdev, DMDevice):
-                continue
-
-            try:
-                # there is a device in the tree already with the same
-                # major/minor as this one but with a different name
-                # XXX this is kind of racy
-                if dmdev.getDMNode() == os.path.basename(sysfs_path):
-                    # XXX should we take the name already in use?
-                    device = dmdev
-                    break
-            except DMError:
-                # This is a little lame, but the VG device is a DMDevice
-                # and it won't have a dm node. At any rate, this is not
-                # important enough to crash the install.
-                log.debug("failed to find dm node for %s" % dmdev.name)
-                continue
-
-        cleanup_luks = udev_device_is_dm_luks(info) and self._cleanup
-        slave_dev = None
-        slave_info = None
-        if device is None:
-            # we couldn't find it, so create it
-            # first, get a list of the slave devs and look them up
-            dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
-            slave_names = os.listdir(dir)
-            for slave_name in slave_names:
-                # if it's a dm-X name, resolve it to a map name first
-                if slave_name.startswith("dm-"):
-                    dev_name = dm.name_from_dm_node(slave_name)
-                else:
-                    dev_name = slave_name.replace("!", "/") # handles cciss
-                slave_dev = self.getDeviceByName(dev_name)
-                path = os.path.normpath("%s/%s" % (dir, slave_name))
-                new_info = udev_get_block_device(os.path.realpath(path)[4:])
-                if not slave_dev:
-                    # we haven't scanned the slave yet, so do it now
-                    if new_info:
-                        self.addUdevDevice(new_info)
-                        slave_dev = self.getDeviceByName(dev_name)
-                        if slave_dev is None:
-                            # if the current slave is still not in
-                            # the tree, something has gone wrong
-                            log.error("failure scanning device %s: could not add slave %s" % (name, dev_name))
-                            return
-
-                if cleanup_luks:
-                    slave_info = new_info
-
-            # try to get the device again now that we've got all the slaves
-            device = self.getDeviceByName(name)
-
-            if device is None and udev_device_is_dm_partition(info):
-                diskname = udev_device_get_dm_partition_disk(info)
-                disk = self.getDeviceByName(diskname)
-                return self.addUdevPartitionDevice(info, disk=disk)
-
-            # if this is a luks device whose map name is not what we expect,
-            # fix up the map name and see if that sorts us out
-            if device is None and cleanup_luks and slave_info and slave_dev:
-                slave_dev.format.mapName = name
-                self.handleUdevLUKSFormat(slave_info, slave_dev)
-
-                # try once more to get the device
-                device = self.getDeviceByName(name)
-
-            # create a device for the livecd OS image(s)
-            if device is None and udev_device_is_dm_livecd(info):
-                device = DMDevice(name, dmUuid=info.get('DM_UUID'),
-                                  sysfsPath=sysfs_path, exists=True,
-                                  parents=[slave_dev])
-                device.protected = True
-                device.controllable = False
-                self._addDevice(device)
-
-            # if we get here, we found all of the slave devices and
-            # something must be wrong -- if all of the slaves are in
-            # the tree, this device should be as well
-            if device is None:
-                devicelibs.lvm.lvm_cc_addFilterRejectRegexp(name)
-                log.warning("ignoring dm device %s" % name)
-
-        return device
-
-    def addUdevMDDevice(self, info):
-        name = udev_device_get_md_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        slaves = []
-        dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
-        slave_names = os.listdir(dir)
-        for slave_name in slave_names:
-            # if it's a dm-X name, resolve it to a map name
-            if slave_name.startswith("dm-"):
-                dev_name = dm.name_from_dm_node(slave_name)
-            else:
-                dev_name = slave_name
-            slave_dev = self.getDeviceByName(dev_name)
-            if slave_dev:
-                slaves.append(slave_dev)
-            else:
-                # we haven't scanned the slave yet, so do it now
-                path = os.path.normpath("%s/%s" % (dir, slave_name))
-                new_info = udev_get_block_device(os.path.realpath(path)[4:])
-                if new_info:
-                    self.addUdevDevice(new_info)
-                    if self.getDeviceByName(dev_name) is None:
-                        # if the current slave is still not in
-                        # the tree, something has gone wrong
-                        log.error("failure scanning device %s: could not add slave %s" % (name, dev_name))
-                        return
-
-        # try to get the device again now that we've got all the slaves
-        device = self.getDeviceByName(name)
-
-        if device is None:
-            device = self.getDeviceByUuid(info.get("MD_UUID"))
-            if device:
-                raise DeviceTreeError("MD RAID device %s already in "
-                                      "devicetree as %s" % (name, device.name))
-
-        # if we get here, we found all of the slave devices and
-        # something must be wrong -- if all of the slaves we in
-        # the tree, this device should be as well
-        if device is None:
-            if name is None:
-                name = udev_device_get_name(info)
-
-            log.error("failed to scan md array %s" % name)
-            try:
-                devicelibs.mdraid.mddeactivate("/dev/" + name)
-            except MDRaidError:
-                log.error("failed to stop broken md array %s" % name)
-
-        return device
-
-    def addUdevPartitionDevice(self, info, disk=None):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        if name.startswith("md"):
-            name = devicelibs.mdraid.name_from_md_node(name)
-            device = self.getDeviceByName(name)
-            if device:
-                return device
-
-        if disk is None:
-            disk_name = os.path.basename(os.path.dirname(sysfs_path))
-            disk_name = disk_name.replace('!','/')
-            if disk_name.startswith("md"):
-                disk_name = devicelibs.mdraid.name_from_md_node(disk_name)
-
-            disk = self.getDeviceByName(disk_name)
-
-        if disk is None:
-            # create a device instance for the disk
-            new_info = udev_get_block_device(os.path.dirname(sysfs_path))
-            if new_info:
-                self.addUdevDevice(new_info)
-                disk = self.getDeviceByName(disk_name)
-
-            if disk is None:
-                # if the current device is still not in
-                # the tree, something has gone wrong
-                log.error("failure scanning device %s" % disk_name)
-                devicelibs.lvm.lvm_cc_addFilterRejectRegexp(name)
-                return
-
-        # Sun disklabels have a partition that spans the entire disk as
-        # partition 3. It does not appear in the partition list. Fantastic.
-        is_sun_magic = (getattr(disk.format, "labelType", None) == "sun" and
-                        udev_device_get_minor(info) == 3)
-
-        # Check that the disk has partitions. If it does not, we must have
-        # reinitialized the disklabel.
-        #
-        # Also ignore partitions on devices we do not support partitioning
-        # of, like logical volumes.
-        if ((not getattr(disk.format, "partitions", None) and not is_sun_magic)
-            or not disk.partitionable):
-            # When we got here because the disk does not have a disklabel
-            # format (ie a biosraid member), or because it is not
-            # partitionable we want LVM to ignore this partition too
-            if disk.format.type != "disklabel" or not disk.partitionable:
-                devicelibs.lvm.lvm_cc_addFilterRejectRegexp(name)
-            log.debug("ignoring partition %s" % name)
-            return
-
-        try:
-            device = PartitionDevice(name, sysfsPath=sysfs_path,
-                                     major=udev_device_get_major(info),
-                                     minor=udev_device_get_minor(info),
-                                     exists=True, parents=[disk])
-        except DeviceError as e:
-            # corner case sometime the kernel accepts a partition table
-            # which gets rejected by parted, in this case we will
-            # prompt to re-initialize the disk, so simply skip the
-            # faulty partitions.
-            log.error("Failed to instantiate PartitionDevice: %s" % e)
-            return
-
-        self._addDevice(device)
-        return device
-
-    def addUdevDiskDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        serial = udev_device_get_serial(info)
-        bus = udev_device_get_bus(info)
-
-        # udev doesn't always provide a vendor.
-        vendor = udev_device_get_vendor(info)
-        if not vendor:
-            vendor = ""
-
-        device = None
-
-        kwargs = { "serial": serial, "vendor": vendor, "bus": bus }
-        if udev_device_is_iscsi(info):
-            diskType = iScsiDiskDevice
-            initiator = udev_device_get_iscsi_initiator(info)
-            target = udev_device_get_iscsi_name(info)
-            address = udev_device_get_iscsi_address(info)
-            port = udev_device_get_iscsi_port(info)
-            nic = udev_device_get_iscsi_nic(info)
-            kwargs["initiator"] = initiator
-            if initiator == self.iscsi.initiator:
-                node = self.iscsi.getNode(target, address, port, nic)
-                kwargs["node"] = node
-                kwargs["ibft"] = node in self.iscsi.ibftNodes
-                kwargs["nic"] = self.iscsi.ifaces.get(node.iface, node.iface)
-                log.info("%s is an iscsi disk" % name)
-            else:
-                # qla4xxx partial offload
-                kwargs["node"] = None
-                kwargs["ibft"] = False
-                kwargs["nic"] = "offload:not_accessible_via_iscsiadm"
-                kwargs["fw_address"] = address
-                kwargs["fw_port"] = port
-                kwargs["fw_name"] = name
-        elif udev_device_is_fcoe(info):
-            diskType = FcoeDiskDevice
-            kwargs["nic"]        = udev_device_get_fcoe_nic(info)
-            kwargs["identifier"] = udev_device_get_fcoe_identifier(info)
-            log.info("%s is an fcoe disk" % name)
-        elif udev_device_get_md_container(info):
-            name = udev_device_get_md_name(info)
-            diskType = MDRaidArrayDevice
-            parentPath = udev_device_get_md_container(info)
-            parentName = devicePathToName(parentPath)
-            container = self.getDeviceByName(parentName)
-            if not container:
-                parentSysName = devicelibs.mdraid.md_node_from_name(parentName)
-                container_sysfs = "/class/block/" + parentSysName
-                container_info = udev_get_block_device(container_sysfs)
-                if not container_info:
-                    log.error("failed to find md container %s at %s"
-                                % (parentName, container_sysfs))
-                    return
-
-                self.addUdevDevice(container_info)
-                container = self.getDeviceByName(parentName)
-                if not container:
-                    log.error("failed to scan md container %s" % parentName)
-                    return
-
-            kwargs["parents"] = [container]
-            kwargs["level"]  = udev_device_get_md_level(info)
-            kwargs["memberDevices"] = int(udev_device_get_md_devices(info))
-            kwargs["uuid"] = udev_device_get_md_uuid(info)
-            kwargs["exists"]  = True
-            del kwargs["serial"]
-            del kwargs["vendor"]
-            del kwargs["bus"]
-        elif udev_device_is_dasd(info):
-            diskType = DASDDevice
-            kwargs["dasd"] = self.dasd
-            kwargs["busid"] = udev_device_get_dasd_bus_id(info)
-            kwargs["opts"] = {}
-
-            for attr in ['readonly', 'use_diag', 'erplog', 'failfast']:
-                kwargs["opts"][attr] = udev_device_get_dasd_flag(info, attr)
-
-            log.info("%s is a dasd device" % name)
-        elif udev_device_is_zfcp(info):
-            diskType = ZFCPDiskDevice
-
-            for attr in ['hba_id', 'wwpn', 'fcp_lun']:
-                kwargs[attr] = udev_device_get_zfcp_attribute(info, attr=attr)
-
-            log.info("%s is a zfcp device" % name)
-        else:
-            diskType = DiskDevice
-            log.info("%s is a disk" % name)
-
-        device = diskType(name,
-                          major=udev_device_get_major(info),
-                          minor=udev_device_get_minor(info),
-                          sysfsPath=sysfs_path, **kwargs)
-        self._addDevice(device)
-        return device
-
-    def addUdevOpticalDevice(self, info):
-        log_method_call(self)
-        # XXX should this be RemovableDevice instead?
-        #
-        # Looks like if it has ID_INSTANCE=0:1 we can ignore it.
-        device = OpticalDevice(udev_device_get_name(info),
-                               major=udev_device_get_major(info),
-                               minor=udev_device_get_minor(info),
-                               sysfsPath=udev_device_get_sysfs_path(info),
-                               vendor=udev_device_get_vendor(info),
-                               model=udev_device_get_model(info))
-        self._addDevice(device)
-        return device
-
-    def addUdevLoopDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        sys_file = "/sys/%s/loop/backing_file" % sysfs_path
-        backing_file = open(sys_file).read().strip()
-        file_device = self.getDeviceByName(backing_file)
-        if not file_device:
-            file_device = FileDevice(backing_file, exists=True)
-            self._addDevice(file_device)
-        device = LoopDevice(name,
-                            parents=[file_device],
-                            sysfsPath=sysfs_path,
-                            exists=True)
-        if not self._cleanup or file_device not in self.diskImages.values():
-            # don't allow manipulation of loop devices other than those
-            # associated with disk images, and then only during cleanup
-            file_device.controllable = False
-            device.controllable = False
-        self._addDevice(device)
-        return device
-
-    def addUdevDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name, info=pprint.pformat(info))
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        # make sure we note the name of every device we see
-        if name not in self.names:
-            self.names.append(name)
-
-        if self.isIgnored(info):
-            log.info("ignoring %s (%s)" % (name, sysfs_path))
-            if name not in self._ignoredDisks:
-                self.addIgnoredDisk(name)
-
-            if udev_device_is_multipath_member(info):
-                # last time we are seeing this mpath member is now, so make sure
-                # LVM ignores its partitions too else a duplicate VG name could
-                # harm us later during partition creation:
-                if udev_device_is_dm(info):
-                    path = "/dev/mapper/%s" % name
-                else:
-                    path = "/dev/%s" % name
-                log.debug("adding partitions on %s to the lvm ignore list" % path)
-                partitions_paths = []
-                try:
-                    partitions_paths = [p.path
-                                       for p in parted.Disk(device=parted.Device(path=path)).partitions]
-                except (_ped.IOException, _ped.DeviceException, _ped.DiskLabelException) as e:
-                    log.error("Parted error scanning partitions on %s:" % path)
-                    log.error(str(e))
-                # slice off the "/dev/" part, lvm filter cares only about the rest
-                partitions_paths = [p[5:] for p in partitions_paths]
-                map(lvm.lvm_cc_addFilterRejectRegexp, partitions_paths)
-            return
-
-        log.info("scanning %s (%s)..." % (name, sysfs_path))
-        device = self.getDeviceByName(name)
-
-        #
-        # The first step is to either look up or create the device
-        #
-        if device:
-            # we successfully looked up the device. skip to format handling.
-            # first, grab the parted.Device while it's active
-            _unused = device.partedDevice
-        elif udev_device_is_loop(info):
-            log.info("%s is a loop device" % name)
-            device = self.addUdevLoopDevice(info)
-        elif udev_device_is_multipath_member(info):
-            device = self.addUdevDiskDevice(info)
-        elif udev_device_is_dm(info) and udev_device_is_dm_mpath(info):
-            log.info("%s is a multipath device" % name)
-            device = self.addUdevDMDevice(info)
-        elif udev_device_is_dm_lvm(info):
-            log.info("%s is an lvm logical volume" % name)
-            device = self.addUdevLVDevice(info)
-        elif udev_device_is_dm(info):
-            log.info("%s is a device-mapper device" % name)
-            device = self.addUdevDMDevice(info)
-        elif udev_device_is_md(info) and not udev_device_get_md_container(info):
-            log.info("%s is an md device" % name)
-            if uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevMDDevice(info)
-        elif udev_device_is_cdrom(info):
-            log.info("%s is a cdrom" % name)
-            device = self.addUdevOpticalDevice(info)
-        elif udev_device_is_biosraid_member(info) and udev_device_is_disk(info):
-            log.info("%s is part of a biosraid" % name)
-            device = DiskDevice(name,
-                            major=udev_device_get_major(info),
-                            minor=udev_device_get_minor(info),
-                            sysfsPath=sysfs_path, exists=True)
-            self._addDevice(device)
-        elif udev_device_is_disk(info):
-            device = self.addUdevDiskDevice(info)
-        elif udev_device_is_partition(info):
-            log.info("%s is a partition" % name)
-            device = self.addUdevPartitionDevice(info)
-        else:
-            log.error("Unknown block device type for: %s" % name)
-            return
-
-        # If this device is protected, mark it as such now. Once the tree
-        # has been populated, devices' protected attribute is how we will
-        # identify protected devices.
-        if device and device.name in self.protectedDevNames:
-            device.protected = True
-            # if this is the live backing device we want to mark its parents
-            # as protected also
-            if device.name == self.liveBackingDevice:
-                for parent in device.parents:
-                    parent.protected = True
-
-        # Don't try to do format handling on drives without media or
-        # if we didn't end up with a device somehow.
-        if not device or not device.mediaPresent:
-            log.debug("no device or no media present")
-            return
-
-        # now handle the device's formatting
-        self.handleUdevDeviceFormat(info, device)
-        log.info("got device: %r" % device)
-        if device.format.type:
-            log.info("got format: %r" % device.format)
-        device.originalFormat = copy.copy(device.format)
-
-    def handleUdevDiskLabelFormat(self, info, device):
-        disklabel_type = info.get("ID_PART_TABLE_TYPE")
-        log_method_call(self, device=device.name, label_type=disklabel_type)
-        # if there is no disklabel on the device
-        if disklabel_type is None and \
-           getFormat(udev_device_get_format(info)).type is not None:
-            log.debug("device %s does not contain a disklabel" % device.name)
-            return
-
-        if device.partitioned:
-            # this device is already set up
-            log.debug("disklabel format on %s already set up" % device.name)
-            return
-
-        try:
-            device.setup()
-        except Exception as e:
-            log.debug("setup of %s failed: %s" % (device.name, e))
-            log.warning("aborting disklabel handler for %s" % device.name)
-            return
-
-        # special handling for unsupported partitioned devices
-        if not device.partitionable:
-            try:
-                format = getFormat("disklabel",
-                                   device=device.path,
-                                   labelType=disklabel_type,
-                                   exists=True)
-            except InvalidDiskLabelError:
-                log.warning("disklabel detected but not usable on %s"
-                            % device.name)
-                pass
-            return
-
-        # we're going to pass the "best" disklabel type into the DiskLabel
-        # constructor, but it only has meaning for non-existent disklabels.
-        labelType = platform.bestDiskLabelType(device)
-
-        try:
-            format = getFormat("disklabel",
-                               device=device.path,
-                               labelType=labelType,
-                               exists=True)
-        except InvalidDiskLabelError:
-            log.info("no usable disklabel on %s" % device.name)
-            return
-        else:
-            device.format = format
-
-    def handleUdevLUKSFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        if not device.format.uuid:
-            log.info("luks device %s has no uuid" % device.path)
-            return
-
-        # look up or create the mapped device
-        if not self.getDeviceByName(device.format.mapName):
-            passphrase = self.__luksDevs.get(device.format.uuid)
-            if device.format.configured:
-                pass
-            elif passphrase:
-                device.format.passphrase = passphrase
-            elif device.format.uuid in self.__luksDevs:
-                log.info("skipping previously-skipped luks device %s"
-                            % device.name)
-            elif self._cleanup or flags.testing:
-                # if we're only building the devicetree so that we can
-                # tear down all of the devices we don't need a passphrase
-                if device.format.status:
-                    # this makes device.configured return True
-                    device.format.passphrase = 'yabbadabbadoo'
-            else:
-                # Try each known passphrase.
-                for passphrase in self.__passphrases:
-                    device.format.passphrase = passphrase
-                    try:
-                        device.format.setup()
-                    except CryptoError:
-                        device.format.passphrase = None
-                    else:
-                        break
-
-            luks_device = LUKSDevice(device.format.mapName,
-                                     parents=[device],
-                                     exists=True)
-            try:
-                luks_device.setup()
-            except (LUKSError, CryptoError, DeviceError) as e:
-                log.info("setup of %s failed: %s" % (device.format.mapName,
-                                                     e))
-                device.removeChild()
-            else:
-                self._addDevice(luks_device)
-        else:
-            log.warning("luks device %s already in the tree"
-                        % device.format.mapName)
-
-    def handleVgLvs(self, vg_device):
-        """ Handle setup of the LV's in the vg_device
-            return True if an LV was setup
-            return False if there was an error, or no more LV's to setup
-        """
-        ret = False
-        vg_name = vg_device.name
-        lv_names = vg_device.lv_names
-        lv_uuids = vg_device.lv_uuids
-        lv_sizes = vg_device.lv_sizes
-        lv_attr = vg_device.lv_attr
-
-        if not vg_device.complete:
-            log.warning("Skipping LVs for incomplete VG %s" % vg_name)
-            return False
-
-        if not lv_names:
-            log.debug("no LVs listed for VG %s" % vg_name)
-            return False
-
-        def lv_attr_cmp(a, b):
-            """ Sort so that mirror images come first and snapshots last. """
-            mirror_chars = "Iil"
-            snapshot_chars = "Ss"
-            if a[0] in mirror_chars and b[0] not in mirror_chars:
-                return -1
-            elif a[0] not in mirror_chars and b[0] in mirror_chars:
-                return 1
-            elif a[0] not in snapshot_chars and b[0] in snapshot_chars:
-                return -1
-            elif a[0] in snapshot_chars and b[0] not in snapshot_chars:
-                return 1
-            else:
-                return 0
-
-        # make a list of indices with mirror volumes up front and snapshots at
-        # the end
-        indices = range(len(lv_names))
-        indices.sort(key=lambda i: lv_attr[i], cmp=lv_attr_cmp)
-        mirrors = {}
-        for index in indices:
-            lv_name = lv_names[index]
-            name = "%s-%s" % (vg_name, lv_name)
-            if lv_attr[index][0] in 'Ss':
-                log.info("found lvm snapshot volume '%s'" % name)
-                origin_name = devicelibs.lvm.lvorigin(vg_name, lv_name)
-                if not origin_name:
-                    log.error("lvm snapshot '%s-%s' has unknown origin"
-                                % (vg_name, lv_name))
-                    continue
-
-                origin = self.getDeviceByName("%s-%s" % (vg_name,
-                                                         origin_name))
-                if not origin:
-                    if origin_name.endswith("_vorigin]"):
-                        log.info("snapshot volume '%s' has vorigin" % name)
-                        vg_device.voriginSnapshots[lv_name] = lv_sizes[index]
-                    else:
-                        log.warning("snapshot lv '%s' origin lv '%s-%s' "
-                                    "not found" % (name,
-                                                   vg_name, origin_name))
-                    continue
-
-                log.debug("adding %dMB to %s snapshot total"
-                            % (lv_sizes[index], origin.name))
-                origin.snapshotSpace += lv_sizes[index]
-                continue
-            elif lv_attr[index][0] == 'v':
-                # skip vorigins
-                continue
-            elif lv_attr[index][0] in 'Ii':
-                # mirror image
-                lv_name = re.sub(r'_mimage.+', '', lv_name[1:-1])
-                name = "%s-%s" % (vg_name, lv_name)
-                if name not in mirrors:
-                    mirrors[name] = {"stripes": 0, "log": 0}
-
-                mirrors[name]["stripes"] += 1
-            elif lv_attr[index][0] == 'l':
-                # log volume
-                lv_name = re.sub(r'_mlog.*', '', lv_name[1:-1])
-                name = "%s-%s" % (vg_name, lv_name)
-                if name not in mirrors:
-                    mirrors[name] = {"stripes": 0, "log": 0}
-
-                mirrors[name]["log"] = lv_sizes[index]
-
-            lv_dev = self.getDeviceByName(name)
-            if lv_dev is None:
-                lv_uuid = lv_uuids[index]
-                lv_size = lv_sizes[index]
-                lv_device = LVMLogicalVolumeDevice(lv_name,
-                                                   vg_device,
-                                                   uuid=lv_uuid,
-                                                   size=lv_size,
-                                                   exists=True)
-                self._addDevice(lv_device)
-                lv_device.setup()
-                ret = True
-
-        for name, mirror in mirrors.items():
-            lv_dev = self.getDeviceByName(name)
-            lv_dev.stripes = mirror["stripes"]
-            lv_dev.logSize = mirror["log"]
-            log.debug("set %s stripes to %d, log size to %dMB, total size %dMB"
-                        % (lv_dev.name, lv_dev.stripes, lv_dev.logSize,
-                           lv_dev.vgSpaceUsed))
-
-        return ret
-
-    def handleUdevLVMPVFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        # lookup/create the VG and LVs
-        try:
-            vg_name = udev_device_get_vg_name(info)
-            vg_uuid = udev_device_get_vg_uuid(info)
-        except KeyError:
-            # no vg name means no vg -- we're done with this pv
-            return
-
-        vg_device = self.getDeviceByUuid(vg_uuid)
-        if vg_device:
-            vg_device._addDevice(device)
-        else:
-            try:
-                vg_size = udev_device_get_vg_size(info)
-                vg_free = udev_device_get_vg_free(info)
-                pe_size = udev_device_get_vg_extent_size(info)
-                pe_count = udev_device_get_vg_extent_count(info)
-                pe_free = udev_device_get_vg_free_extents(info)
-                pv_count = udev_device_get_vg_pv_count(info)
-            except (KeyError, ValueError) as e:
-                log.warning("invalid data for %s: %s" % (device.name, e))
-                return
-
-            vg_device = LVMVolumeGroupDevice(vg_name,
-                                             device,
-                                             uuid=vg_uuid,
-                                             size=vg_size,
-                                             free=vg_free,
-                                             peSize=pe_size,
-                                             peCount=pe_count,
-                                             peFree=pe_free,
-                                             pvCount=pv_count,
-                                             exists=True)
-            self._addDevice(vg_device)
-
-        # Now we add any lv info found in this pv to the vg_device, we
-        # do this for all pvs as pvs only contain lv info for lvs which they
-        # contain themselves
-        try:
-            lv_names = udev_device_get_lv_names(info)
-            lv_uuids = udev_device_get_lv_uuids(info)
-            lv_sizes = udev_device_get_lv_sizes(info)
-            lv_attr = udev_device_get_lv_attr(info)
-        except KeyError as e:
-            log.warning("invalid data for %s: %s" % (device.name, e))
-            return
-
-        for i in range(len(lv_names)):
-            # Skip empty and already added lvs
-            if not lv_names[i] or lv_names[i] in vg_device.lv_names:
-                continue
-
-            vg_device.lv_names.append(lv_names[i])
-            vg_device.lv_uuids.append(lv_uuids[i])
-            vg_device.lv_sizes.append(lv_sizes[i])
-            vg_device.lv_attr.append(lv_attr[i])
-
-            name = "%s-%s" % (vg_name, lv_names[i])
-            if name not in self.names:
-                self.names.append(name)
-
-    def handleUdevMDMemberFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        # either look up or create the array device
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        md_array = self.getDeviceByUuid(device.format.mdUuid)
-        if device.format.mdUuid and md_array:
-            md_array._addDevice(device)
-        else:
-            # create the array with just this one member
-            try:
-                # level is reported as, eg: "raid1"
-                md_level = udev_device_get_md_level(info)
-                md_devices = int(udev_device_get_md_devices(info))
-                md_uuid = udev_device_get_md_uuid(info)
-            except (KeyError, ValueError) as e:
-                log.warning("invalid data for %s: %s" % (name, e))
-                return
-
-            md_name = None
-            md_metadata = None
-
-            # check the list of devices udev knows about to see if the array
-            # this device belongs to is already active
-            for dev in udev_get_block_devices():
-                if not udev_device_is_md(dev):
-                    continue
-
-                try:
-                    dev_uuid = udev_device_get_md_uuid(dev)
-                    dev_level = udev_device_get_md_level(dev)
-                except KeyError:
-                    continue
-
-                if dev_uuid is None or dev_level is None:
-                    continue
-
-                if dev_uuid == md_uuid and dev_level == md_level:
-                    md_name = udev_device_get_md_name(dev)
-                    md_metadata = dev.get("MD_METADATA")
-                    break
-
-            md_info = devicelibs.mdraid.mdexamine(device.path)
-            if not md_metadata:
-                md_metadata = md_info.get("metadata", "0.90")
-
-            if not md_name:
-                md_path = md_info.get("device", "")
-                if md_path:
-                    md_name = devicePathToName(md_path)
-                    if re.match(r'md\d+$', md_name):
-                        # md0 -> 0
-                        md_name = md_name[2:]
-
-                    if md_name:
-                        array = self.getDeviceByName(md_name)
-                        if array and array.uuid != md_uuid:
-                            log.error("found multiple devices with the name %s"
-                                        % md_name)
-
-            log.info("using name %s for md array containing member %s"
-                        % (md_name, device.name))
-            try:
-                md_array = MDRaidArrayDevice(md_name,
-                                             level=md_level,
-                                             memberDevices=md_devices,
-                                             uuid=md_uuid,
-                                             metadataVersion=md_metadata,
-                                             exists=True)
-            except ValueError as e:
-                log.error("failed to create md array: %s" % e)
-                return
-
-            md_array.updateSysfsPath()
-            md_array._addDevice(device)
-            self._addDevice(md_array)
-
-    def handleMultipathMemberFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-
-        name = udev_device_get_multipath_name(info)
-        if self.__multipaths.has_key(name):
-            mp = self.__multipaths[name]
-            mp.addParent(device)
-        else:
-            mp = MultipathDevice(name, info, parents=[device])
-            self.__multipaths[name] = mp
-
-    def handleUdevDMRaidMemberFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        major = udev_device_get_major(info)
-        minor = udev_device_get_minor(info)
-
-        def _all_ignored(rss):
-            retval = True
-            for rs in rss:
-                if rs.name not in self._ignoredDisks:
-                    retval = False
-                    break
-            return retval
-
-        # Have we already created the DMRaidArrayDevice?
-        rss = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
-                                            major=major, minor=minor)
-        if len(rss) == 0:
-            # we ignore the device in the hope that all the devices
-            # from this set will be ignored.
-            self.unusedRaidMembers.append(device.name)
-            self.addIgnoredDisk(device.name)
-            return
-
-        # We ignore the device if all the rss are in self._ignoredDisks
-        if _all_ignored(rss):
-            self.addIgnoredDisk(device.name)
-            return
-
-        for rs in rss:
-            dm_array = self.getDeviceByName(rs.name)
-            if dm_array is not None:
-                # We add the new device.
-                dm_array._addDevice(device)
-            else:
-                # Activate the Raid set.
-                rs.activate(mknod=True)
-                dm_array = DMRaidArrayDevice(rs.name,
-                                             raidSet=rs,
-                                             parents=[device])
-
-                self._addDevice(dm_array)
-
-                # Wait for udev to scan the just created nodes, to avoid a race
-                # with the udev_get_block_device() call below.
-                udev_settle()
-
-                # Get the DMRaidArrayDevice a DiskLabel format *now*, in case
-                # its partitions get scanned before it does.
-                dm_array.updateSysfsPath()
-                dm_array_info = udev_get_block_device(dm_array.sysfsPath)
-                self.handleUdevDiskLabelFormat(dm_array_info, dm_array)
-
-                # Use the rs's object on the device.
-                # pyblock can return the memebers of a set and the
-                # device has the attribute to hold it.  But ATM we
-                # are not really using it. Commenting this out until
-                # we really need it.
-                #device.format.raidmem = block.getMemFromRaidSet(dm_array,
-                #        major=major, minor=minor, uuid=uuid, name=name)
-
-    def handleBTRFSFormat(self, info, device):
-        log_method_call(self, name=device.name)
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-
-        btrfs_dev = None
-        for d in self.devices:
-            if isinstance(d, BTRFSVolumeDevice) and d.uuid == uuid:
-                btrfs_dev = d
-                break
-
-        if btrfs_dev:
-            log.info("found btrfs volume %s" % btrfs_dev.name)
-            btrfs_dev._addDevice(device)
-        else:
-            label = udev_device_get_label(info)
-            log.info("creating btrfs volume btrfs.%s" % label)
-            btrfs_dev = BTRFSVolumeDevice(label, parents=[device], uuid=uuid,
-                                          exists=True)
-            self._addDevice(btrfs_dev)
-
-        if not btrfs_dev.subvolumes:
-            for subvol_dict in btrfs_dev.listSubVolumes():
-                vol_id = subvol_dict["id"]
-                vol_path = subvol_dict["path"]
-                if vol_path in [sv.name for sv in btrfs_dev.subvolumes]:
-                    continue
-                fmt = getFormat("btrfs", device=btrfs_dev.path, exists=True,
-                                mountopts="subvol=%s" % vol_path)
-                subvol = BTRFSSubVolumeDevice(vol_path,
-                                              vol_id=vol_id,
-                                              format=fmt,
-                                              parents=[btrfs_dev],
-                                              exists=True)
-                self._addDevice(subvol)
-
-    def handleUdevDeviceFormat(self, info, device):
-        log_method_call(self, name=getattr(device, "name", None))
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        label = udev_device_get_label(info)
-        format_type = udev_device_get_format(info)
-        serial = udev_device_get_serial(info)
-
-        # Now, if the device is a disk, see if there is a usable disklabel.
-        # If not, see if the user would like to create one.
-        # XXX ignore disklabels on multipath or biosraid member disks
-        if not udev_device_is_biosraid_member(info) and \
-           not udev_device_is_multipath_member(info):
-            self.handleUdevDiskLabelFormat(info, device)
-            if device.partitioned or self.isIgnored(info) or \
-               (not device.partitionable and
-                device.format.type == "disklabel"):
-                # If the device has a disklabel, or the user chose not to
-                # create one, we are finished with this device. Otherwise
-                # it must have some non-disklabel formatting, in which case
-                # we fall through to handle that.
-                return
-
-        format = None
-        if (not device) or (not format_type) or device.format.type:
-            # this device has no formatting or it has already been set up
-            # FIXME: this probably needs something special for disklabels
-            log.debug("no type or existing type for %s, bailing" % (name,))
-            return
-
-        # set up the common arguments for the format constructor
-        args = [format_type]
-        kwargs = {"uuid": uuid,
-                  "label": label,
-                  "device": device.path,
-                  "serial": serial,
-                  "exists": True}
-
-        # set up type-specific arguments for the format constructor
-        if format_type == "multipath_member":
-            kwargs["multipath_members"] = self.getDevicesBySerial(serial)
-        elif format_type == "crypto_LUKS":
-            # luks/dmcrypt
-            kwargs["name"] = "luks-%s" % uuid
-        elif format_type in formats.mdraid.MDRaidMember._udevTypes:
-            # mdraid
-            try:
-                kwargs["mdUuid"] = udev_device_get_md_uuid(info)
-            except KeyError:
-                log.warning("mdraid member %s has no md uuid" % name)
-            kwargs["biosraid"] = udev_device_is_biosraid_member(info)
-        elif format_type == "LVM2_member":
-            # lvm
-            try:
-                kwargs["vgName"] = udev_device_get_vg_name(info)
-            except KeyError as e:
-                log.warning("PV %s has no vg_name" % name)
-            try:
-                kwargs["vgUuid"] = udev_device_get_vg_uuid(info)
-            except KeyError:
-                log.warning("PV %s has no vg_uuid" % name)
-            try:
-                kwargs["peStart"] = udev_device_get_pv_pe_start(info)
-            except KeyError:
-                log.warning("PV %s has no pe_start" % name)
-        elif format_type == "vfat":
-            # efi magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                efi = formats.getFormat("efi")
-                if efi.minSize <= device.size <= efi.maxSize:
-                    args[0] = "efi"
-        elif format_type == "hfs":
-            # apple bootstrap magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                apple = formats.getFormat("appleboot")
-                if apple.minSize <= device.size <= apple.maxSize:
-                    args[0] = "appleboot"
-        elif format_type == "btrfs":
-            # the format's uuid attr will contain the UUID_SUB, while the
-            # overarching volume UUID will be stored as volUUID
-            kwargs["uuid"] = info["ID_FS_UUID_SUB"]
-            kwargs["volUUID"] = uuid
-
-        try:
-            log.info("type detected on '%s' is '%s'" % (name, format_type,))
-            device.format = formats.getFormat(*args, **kwargs)
-        except FSError:
-            log.warning("type '%s' on '%s' invalid, assuming no format" %
-                      (format_type, name,))
-            device.format = formats.DeviceFormat()
-            return
-
-        #
-        # now do any special handling required for the device's format
-        #
-        if device.format.type == "luks":
-            self.handleUdevLUKSFormat(info, device)
-        elif device.format.type == "mdmember":
-            self.handleUdevMDMemberFormat(info, device)
-        elif device.format.type == "dmraidmember":
-            self.handleUdevDMRaidMemberFormat(info, device)
-        elif device.format.type == "lvmpv":
-            self.handleUdevLVMPVFormat(info, device)
-        elif device.format.type == "multipath_member":
-            self.handleMultipathMemberFormat(info, device)
-        elif device.format.type == "btrfs":
-            self.handleBTRFSFormat(info, device)
-
-    def updateDeviceFormat(self, device):
-        log.info("updating format of device: %s" % device)
-        try:
-            util.notify_kernel("/sys%s" % device.sysfsPath)
-        except (ValueError, IOError) as e:
-            log.warning("failed to notify kernel of change: %s" % e)
-
-        udev_settle()
-        info = udev_get_device(device.sysfsPath)
-        self.handleUdevDeviceFormat(info, device)
-        if device.format.type:
-            log.info("got format: %s" % device.format)
-
-    def _handleInconsistencies(self):
-        for vg in [d for d in self.devices if d.type == "lvmvg"]:
-            if vg.complete:
-                continue
-
-            # Make sure lvm doesn't get confused by PVs that belong to
-            # incomplete VGs. We will remove the PVs from the blacklist when/if
-            # the time comes to remove the incomplete VG and its PVs.
-            for pv in vg.pvs:
-                devicelibs.lvm.lvm_cc_addFilterRejectRegexp(pv.name)
-
-    def hide(self, device):
-        for d in self.getChildren(device):
-            self.hide(d)
-
-        log.info("hiding device %s %s (id %d)" % (device.type,
-                                                  device.name,
-                                                  device.id))
-
-        for action in reversed(self._actions):
-            if not action.device.dependsOn(device) and action.device != device:
-                continue
-
-            log.debug("cancelling action: %s" % action)
-            try:
-                action.cancel()
-            except Exception:
-                log.warning("failed to cancel action while hiding %s: %s"
-                            % (device.name, action))
-            finally:
-                self._actions.remove(action)
-
-        # XXX modifications that do not require actions, like setting a
-        #     mountpoint, will not be reversed here
-
-        # we're intentionally not modifying self.names here
-        self._devices.remove(device)
-        self._hidden.append(device)
-        lvm.lvm_cc_addFilterRejectRegexp(device.name)
-        for parent in device.parents:
-            parent.removeChild()
-
-    def unhide(self, device):
-        # the hidden list should be in leaves-first order
-        for hidden in reversed(self._hidden):
-            if hidden == device or hidden.dependsOn(device):
-                log.info("unhiding device %s %s (id %d)" % (hidden.type,
-                                                            hidden.name,
-                                                            hidden.id))
-                self._hidden.remove(hidden)
-                self._devices.append(hidden)
-                lvm.lvm_cc_removeFilterRejectRegexp(hidden.name)
-                for parent in device.parents:
-                    parent.addChild()
-
-    def _setupLvs(self):
-        ret = False
-
-        for device in self.getDevicesByType("lvmvg"):
-            if self.handleVgLvs(device):
-                ret = True
-
-        return ret
-
-    def setupDiskImages(self):
-        """ Set up devices to represent the disk image files. """
-        for (name, path) in self.diskImages.items():
-            log.info("setting up disk image file '%s' as '%s'" % (path, name))
-            try:
-                filedev = FileDevice(path, exists=True)
-                filedev.setup()
-                log.debug("%s" % filedev)
-
-                loop_name = devicelibs.loop.get_loop_name(filedev.path)
-                loop_sysfs = None
-                if loop_name:
-                    loop_sysfs = "/class/block/%s" % loop_name
-                loopdev = LoopDevice(name=loop_name,
-                                     parents=[filedev],
-                                     sysfsPath=loop_sysfs,
-                                     exists=True)
-                loopdev.setup()
-                log.debug("%s" % loopdev)
-                dmdev = DMLinearDevice(name,
-                                       dmUuid="ANACONDA-%s" % name,
-                                       parents=[loopdev],
-                                       exists=True)
-                dmdev.setup()
-                dmdev.updateSysfsPath()
-                log.debug("%s" % dmdev)
-            except (ValueError, DeviceError) as e:
-                log.error("failed to set up disk image: %s" % e)
-            else:
-                self._addDevice(filedev)
-                self._addDevice(loopdev)
-                self._addDevice(dmdev)
-                info = udev_get_block_device(dmdev.sysfsPath)
-                self.addUdevDevice(info)
-
-    def backupConfigs(self, restore=False):
-        """ Create a backup copies of some storage config files. """
-        configs = ["/etc/mdadm.conf", "/etc/multipath.conf"]
-        for cfg in configs:
-            if restore:
-                src = cfg + ".anacbak"
-                dst = cfg
-                func = os.rename
-                op = "restore from backup"
-            else:
-                src = cfg
-                dst = cfg + ".anacbak"
-                func = shutil.copy2
-                op = "create backup copy"
-
-            if os.access(dst, os.W_OK):
-                try:
-                    os.unlink(dst)
-                except OSError as e:
-                    msg = str(e)
-                    log.info("failed to remove %s: %s" % (dst, msg))
-
-            if os.access(src, os.W_OK):
-                # copy the config to a backup with extension ".anacbak"
-                try:
-                    func(src, dst)
-                except (IOError, OSError) as e:
-                    msg = str(e)
-                    log.error("failed to %s of %s: %s" % (op, cfg, msg))
-            elif restore and os.access(cfg, os.W_OK):
-                # remove the config since we created it
-                log.info("removing anaconda-created %s" % cfg)
-                try:
-                    os.unlink(cfg)
-                except OSError as e:
-                    msg = str(e)
-                    log.error("failed to remove %s: %s" % (cfg, msg))
-            else:
-                # don't try to backup non-existent configs
-                log.info("not going to %s of non-existent %s" % (op, cfg))
-
-    def restoreConfigs(self):
-        self.backupConfigs(restore=True)
-
-    def populate(self, cleanupOnly=False):
-        """ Locate all storage devices. """
-        self.backupConfigs()
-        if cleanupOnly:
-            self._cleanup = True
-
-        try:
-            self._populate()
-        except Exception:
-            raise
-        finally:
-            self.restoreConfigs()
-
-    def _populate(self):
-        log.info("DeviceTree.populate: ignoredDisks is %s ; exclusiveDisks is %s"
-                    % (self._ignoredDisks, self.exclusiveDisks))
-
-        self.setupDiskImages()
-
-        # mark the tree as unpopulated so exception handlers can tell the
-        # exception originated while finding storage devices
-        self.populated = False
-
-        # resolve the protected device specs to device names
-        for spec in self.protectedDevSpecs:
-            name = udev_resolve_devspec(spec)
-            log.debug("protected device spec %s resolved to %s" % (spec, name))
-            if name:
-                self.protectedDevNames.append(name)
-
-        # FIXME: the backing dev for the live image can't be used as an
-        # install target.  note that this is a little bit of a hack
-        # since we're assuming that /run/initramfs/live will exist
-        for mnt in open("/proc/mounts").readlines():
-            if " /run/initramfs/live " not in mnt:
-                continue
-
-            live_device_name = mnt.split()[0].split("/")[-1]
-            log.info("%s looks to be the live device; marking as protected"
-                     % (live_device_name,))
-            self.protectedDevNames.append(live_device_name)
-            self.liveBackingDevice = live_device_name
-            break
-
-        old_devices = {}
-
-        if os.access("/etc/multipath.conf", os.W_OK):
-            self.__multipathConfigWriter.writeConfig(self.mpathFriendlyNames)
-            self.topology = devicelibs.mpath.MultipathTopology(udev_get_block_devices())
-            log.info("devices to scan: %s" %
-                     [d['name'] for d in self.topology.devices_iter()])
-            for dev in self.topology.devices_iter():
-                # avoid the problems caused by encountering multipath devices in
-                # this loop by simply skipping all dm devices here
-                if dev['name'].startswith("dm-"):
-                    log.debug("Skipping a device mapper drive (%s) for now" % dev['name'])
-                    continue
-
-                old_devices[dev['name']] = dev
-                self.addUdevDevice(dev)
-
-            # Having found all the disks, we can now find all the multipaths built
-            # upon them.
-            whitelist = []
-            mpaths = self.__multipaths.values()
-            mpaths.sort(key=lambda d: d.name)
-            for mp in mpaths:
-                log.info("adding mpath device %s" % mp.name)
-                mp.setup()
-                mp.updateSysfsPath()
-                mp_info = udev_get_block_device(mp.sysfsPath)
-                if mp_info is None or self.isIgnored(mp_info):
-                    mp.teardown()
-                    continue
-
-                whitelist.append(mp.name)
-                for p in mp.parents:
-                    whitelist.append(p.name)
-                self.__multipathConfigWriter.addMultipathDevice(mp)
-                self._addDevice(mp)
-                self.addUdevDevice(mp_info)
-            for d in self.devices:
-                if not d.name in whitelist:
-                    self.__multipathConfigWriter.addBlacklistDevice(d)
-            self.__multipathConfigWriter.writeConfig(self.mpathFriendlyNames)
-        else:
-            log.info("Skipping multipath detection due to running as non-root.")
-
-        # Now, loop and scan for devices that have appeared since the two above
-        # blocks or since previous iterations.
-        while True:
-            devices = []
-            new_devices = udev_get_block_devices()
-
-            for new_device in new_devices:
-                if not old_devices.has_key(new_device['name']):
-                    old_devices[new_device['name']] = new_device
-                    devices.append(new_device)
-
-            if len(devices) == 0:
-                # nothing is changing -- time to setup lvm lvs and scan them
-                # we delay this till all other devices are scanned so that
-                # 1) the lvm filter for ignored disks is completely setup
-                # 2) we have checked all devs for duplicate vg names
-                if self._setupLvs():
-                    # remove any logical volume devices from old_devices so
-                    # they will be re-scanned to get their formatting handled
-                    for (old_name, old_device) in old_devices.items():
-                        if udev_device_is_dm_lvm(old_device):
-                            del old_devices[old_name]
-                    continue
-                # nothing is changing -- we are finished building devices
-                break
-
-            log.info("devices to scan: %s" % [d['name'] for d in devices])
-            for dev in devices:
-                self.addUdevDevice(dev)
-
-        self.populated = True
-
-        # After having the complete tree we make sure that the system
-        # inconsistencies are ignored or resolved.
-        self._handleInconsistencies()
-
-        self.teardownAll()
-
-    def teardownAll(self):
-        """ Run teardown methods on all devices. """
-        for device in self.leaves:
-            if device.protected:
-                continue
-
-            try:
-                device.teardown(recursive=True)
-            except StorageError as e:
-                log.info("teardown of %s failed: %s" % (device.name, e))
-
-    def setupAll(self):
-        """ Run setup methods on all devices. """
-        for device in self.leaves:
-            try:
-                device.setup()
-            except DeviceError as (msg, name):
-                log.error("setup of %s failed: %s" % (device.name, msg))
-
-    def getDeviceBySysfsPath(self, path):
-        if not path:
-            return None
-
-        found = None
-        for device in self._devices:
-            if device.sysfsPath == path:
-                found = device
-                break
-
-        log_method_return(self, found)
-        return found
-
-    def getDeviceByUuid(self, uuid):
-        if not uuid:
-            return None
-
-        found = None
-        for device in self._devices:
-            if device.uuid == uuid:
-                found = device
-                break
-            elif device.format.uuid == uuid:
-                found = device
-                break
-
-        log_method_return(self, found)
-        return found
-
-    def getDevicesBySerial(self, serial):
-        devices = []
-        for device in self._devices:
-            if not hasattr(device, "serial"):
-                log.warning("device %s has no serial attr" % device.name)
-                continue
-            if device.serial == serial:
-                devices.append(device)
-
-        log_method_return(self, devices)
-        return devices
-
-    def getDeviceByLabel(self, label):
-        if not label:
-            return None
-
-        found = None
-        for device in self._devices:
-            _label = getattr(device.format, "label", None)
-            if not _label:
-                continue
-
-            if _label == label:
-                found = device
-                break
-
-        log_method_return(self, found)
-        return found
-
-    def getDeviceByName(self, name):
-        log_method_call(self, name=name)
-        if not name:
-            log_method_return(self, None)
-            return None
-
-        found = None
-        for device in self._devices:
-            if not getattr(device, "complete", True):
-                continue
-
-            if device.name == name:
-                found = device
-                break
-            elif (device.type == "lvmlv" or device.type == "lvmvg") and \
-                    device.name == name.replace("--","-"):
-                found = device
-                break
-
-        log_method_return(self, str(found))
-        return found
-
-    def getDeviceByPath(self, path, preferLeaves=True):
-        log_method_call(self, path=path)
-        if not path:
-            log_method_return(self, None)
-            return None
-
-        found = None
-        leaf = None
-        other = None
-        for device in self._devices:
-            if not getattr(device, "complete", True):
-                continue
-
-            if (device.path == path or
-                ((device.type == "lvmlv" or device.type == "lvmvg") and
-                 device.path == path.replace("--","-"))):
-                if device.isleaf and not leaf:
-                    leaf = device
-                elif not other:
-                    other = device
-
-        if preferLeaves:
-            all_devs = [leaf, other]
-        else:
-            all_devs = [other, leaf]
-        all_devs = [d for d in all_devs if d]
-        if all_devs:
-            found = all_devs[0]
-
-        log_method_return(self, str(found))
-        return found
-
-    def getDevicesByType(self, device_type):
-        # TODO: expand this to catch device format types
-        return [d for d in self._devices if d.type == device_type]
-
-    def getDevicesByInstance(self, device_class):
-        return [d for d in self._devices if isinstance(d, device_class)]
-
-    def getDeviceByID(self, id_num):
-        for device in self._devices:
-            if device.id == id_num:
-                return device
-
-    @property
-    def devices(self):
-        """ List of device instances """
-        devices = []
-        for device in self._devices:
-            if not getattr(device, "complete", True):
-                continue
-
-            if device.uuid and device.uuid in [d.uuid for d in devices] and \
-               not isinstance(device, NoDevice):
-                raise DeviceTreeError("duplicate uuids in device tree")
-
-            devices.append(device)
-
-        return devices
-
-    @property
-    def filesystems(self):
-        """ List of filesystems. """
-        #""" Dict with mountpoint keys and filesystem values. """
-        filesystems = []
-        for dev in self.leaves:
-            if dev.format and getattr(dev.format, 'mountpoint', None):
-                filesystems.append(dev.format)
-
-        return filesystems
-
-    @property
-    def uuids(self):
-        """ Dict with uuid keys and Device values. """
-        uuids = {}
-        for dev in self._devices:
-            try:
-                uuid = dev.uuid
-            except AttributeError:
-                uuid = None
-
-            if uuid:
-                uuids[uuid] = dev
-
-            try:
-                uuid = dev.format.uuid
-            except AttributeError:
-                uuid = None
-
-            if uuid:
-                uuids[uuid] = dev
-
-        return uuids
-
-    @property
-    def labels(self):
-        """ Dict with label keys and Device values.
-
-            FIXME: duplicate labels are a possibility
-        """
-        labels = {}
-        for dev in self._devices:
-            # don't include btrfs member devices
-            if getattr(dev.format, "label", None) and \
-               (dev.format.type != "btrfs" or isinstance(dev, BTRFSDevice)):
-                labels[dev.format.label] = dev
-
-        return labels
-
-    @property
-    def leaves(self):
-        """ List of all devices upon which no other devices exist. """
-        leaves = [d for d in self._devices if d.isleaf]
-        return leaves
-
-    def getChildren(self, device):
-        """ Return a list of a device's children. """
-        return [c for c in self._devices if device in c.parents]
-
-    def resolveDevice(self, devspec, blkidTab=None, cryptTab=None, options=None):
-        # find device in the tree
-        device = None
-        if devspec.startswith("UUID="):
-            # device-by-uuid
-            uuid = devspec.partition("=")[2]
-            if ((uuid.startswith('"') and uuid.endswith('"')) or
-                (uuid.startswith("'") and uuid.endswith("'"))):
-                uuid = uuid[1:-1]
-            device = self.uuids.get(uuid)
-        elif devspec.startswith("LABEL="):
-            # device-by-label
-            label = devspec.partition("=")[2]
-            if ((label.startswith('"') and label.endswith('"')) or
-                (label.startswith("'") and label.endswith("'"))):
-                label = label[1:-1]
-            device = self.labels.get(label)
-        elif re.match(r'(0x)?[A-Za-z0-9]{2}(p\d+)?$', devspec):
-            # BIOS drive number
-            spec = int(devspec, 16)
-            for (edd_name, edd_number) in devicelibs.edd.edd_dict.items():
-                if edd_number == spec:
-                    device = self.getDeviceByName(edd_name)
-                    break
-        else:
-            if not devspec.startswith("/dev/"):
-                device = self.getDeviceByName(devspec)
-                if not device:
-                    devspec = "/dev/" + devspec
-
-            if not device:
-                if devspec.startswith("/dev/disk/"):
-                    devspec = os.path.realpath(devspec)
-
-                if devspec.startswith("/dev/dm-"):
-                    dm_name = devicelibs.dm.name_from_dm_node(devspec[5:])
-                    if dm_name:
-                        devspec = "/dev/mapper/" + dm_name
-
-                # device path
-                device = self.getDeviceByPath(devspec)
-
-            if device is None:
-                if blkidTab:
-                    # try to use the blkid.tab to correlate the device
-                    # path with a UUID
-                    blkidTabEnt = blkidTab.get(devspec)
-                    if blkidTabEnt:
-                        log.debug("found blkid.tab entry for '%s'" % devspec)
-                        uuid = blkidTabEnt.get("UUID")
-                        if uuid:
-                            device = self.getDeviceByUuid(uuid)
-                            if device:
-                                devstr = device.name
-                            else:
-                                devstr = "None"
-                            log.debug("found device '%s' in tree" % devstr)
-                        if device and device.format and \
-                           device.format.type == "luks":
-                            map_name = device.format.mapName
-                            log.debug("luks device; map name is '%s'" % map_name)
-                            mapped_dev = self.getDeviceByName(map_name)
-                            if mapped_dev:
-                                device = mapped_dev
-
-                if device is None and cryptTab and \
-                   devspec.startswith("/dev/mapper/"):
-                    # try to use a dm-crypt mapping name to 
-                    # obtain the underlying device, possibly
-                    # using blkid.tab
-                    cryptTabEnt = cryptTab.get(devspec.split("/")[-1])
-                    if cryptTabEnt:
-                        luks_dev = cryptTabEnt['device']
-                        try:
-                            device = self.getChildren(luks_dev)[0]
-                        except IndexError as e:
-                            pass
-                elif device is None:
-                    # dear lvm: can we please have a few more device nodes
-                    #           for each logical volume?
-                    #           three just doesn't seem like enough.
-                    name = devspec[5:]      # strip off leading "/dev/"
-                    (vg_name, slash, lv_name) = name.partition("/")
-                    if lv_name and not "/" in lv_name:
-                        # looks like we may have one
-                        lv = "%s-%s" % (vg_name, lv_name)
-                        device = self.getDeviceByName(lv)
-
-        # check mount options for btrfs volumes in case it's a subvol
-        if device and device.type == "btrfs volume" and options:
-            attr = None
-            if "subvol=" in options:
-                attr = "name"
-                val = util.get_option_value("subvol", options)
-            elif "subvolid=" in options:
-                attr = "vol_id"
-                val = util.get_option_value("subvolid", options)
-
-            if attr and val:
-                for subvol in device.subvolumes:
-                    if getattr(subvol, attr, None) == val:
-                        device = subvol
-                        break
-
-        if device:
-            log.debug("resolved '%s' to '%s' (%s)" % (devspec, device.name, device.type))
-        else:
-            log.debug("failed to resolve '%s'" % devspec)
-        return device
diff --git a/pyanaconda/storage/errors.py b/pyanaconda/storage/errors.py
deleted file mode 100644
index aad1d00..0000000
--- a/pyanaconda/storage/errors.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# errors.py
-# Exception classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-class StorageError(Exception):
-    def __init__(self, *args, **kwargs):
-        self.hardware_fault = kwargs.pop("hardware_fault", False)
-        super(StorageError, self).__init__(*args, **kwargs)
-
-class NoDisksError(StorageError):
-    pass
-
-class ErrorRecoveryFailure(StorageError):
-    pass
-
-# Device
-class DeviceError(StorageError):
-    pass
-
-class DeviceCreateError(DeviceError):
-    pass
-
-class DeviceDestroyError(DeviceError):
-    pass
-
-class DeviceResizeError(DeviceError):
-    pass
-
-class DeviceSetupError(DeviceError):
-    pass
-
-class DeviceTeardownError(DeviceError):
-    pass
-
-class DeviceUserDeniedFormatError(DeviceError):
-    pass
-
-# DeviceFormat
-class DeviceFormatError(StorageError):
-    pass
-
-class FormatCreateError(DeviceFormatError):
-    pass
-
-class FormatDestroyError(DeviceFormatError):
-    pass
-
-class FormatSetupError(DeviceFormatError):
-    pass
-
-class FormatTeardownError(DeviceFormatError):
-    pass
-
-class DMRaidMemberError(DeviceFormatError):
-    pass
-
-class MultipathMemberError(DeviceFormatError):
-    pass
-
-class FSError(DeviceFormatError):
-    pass
-
-class FSResizeError(FSError):
-    pass
-
-class DirtyFSError(FSError):
-    pass
-
-class LUKSError(DeviceFormatError):
-    pass
-
-class MDMemberError(DeviceFormatError):
-    pass
-
-class PhysicalVolumeError(DeviceFormatError):
-    pass
-
-class SinglePhysicalVolumeError(DeviceFormatError):
-    pass
-
-class SwapSpaceError(DeviceFormatError):
-    pass
-
-class DiskLabelError(DeviceFormatError):
-    pass
-
-class InvalidDiskLabelError(DiskLabelError):
-    pass
-
-class DiskLabelCommitError(DiskLabelError):
-    pass
-
-# devicelibs
-class SwapError(StorageError):
-    pass
-
-class SuspendError(SwapError):
-    pass
-
-class OldSwapError(SwapError):
-    pass
-
-class UnknownSwapError(SwapError):
-    pass
-
-class MDRaidError(StorageError):
-    pass
-
-class DMError(StorageError):
-    pass
-
-class LVMError(StorageError):
-    pass
-
-class CryptoError(StorageError):
-    pass
-
-class MPathError(StorageError):
-    pass
-
-class LoopError(StorageError):
-    pass
-
-class BTRFSError(StorageError):
-    pass
-
-# DeviceTree
-class DeviceTreeError(StorageError):
-    pass
-
-class DeviceNotFoundError(StorageError):
-    pass
-
-# DeviceAction
-class DeviceActionError(StorageError):
-    pass
-
-# partitioning
-class PartitioningError(StorageError):
-    pass
-
-class NotEnoughFreeSpaceError(StorageError):
-    pass
-
-# udev
-class UdevError(StorageError):
-    pass
-
-# fstab
-class UnrecognizedFSTabEntryError(StorageError):
-    pass
-
-class FSTabTypeMismatchError(StorageError):
-    pass
-
-# dasd
-class DasdFormatError(StorageError):
-    pass
-
-# size
-class SizeParamsError(StorageError):
-    pass
-
-class SizeNotPositiveError(StorageError):
-    pass
-
-class SizePlacesError(StorageError):
-    pass
-
-# probing
-class UnknownSourceDeviceError(StorageError):
-    pass
-
-class NoDisksError(StorageError):
-    pass
diff --git a/pyanaconda/storage/fcoe.py b/pyanaconda/storage/fcoe.py
deleted file mode 100644
index 8e8e301..0000000
--- a/pyanaconda/storage/fcoe.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#
-# fcoe.py - fcoe class
-#
-# Copyright (C) 2009  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-from . import util
-from .udev import udev_settle
-#from pyanaconda import isys
-from . import ROOT_PATH
-import logging
-import time
-log = logging.getLogger("storage")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-_fcoe_module_loaded = False
-
-def has_fcoe():
-    global _fcoe_module_loaded
-    if not _fcoe_module_loaded:
-        util.run_program(["modprobe", "fcoe"])
-        _fcoe_module_loaded = True
-        if "bnx2x" in util.lsmod():
-            log.info("fcoe: loading bnx2fc")
-            util.run_program(["modprobe", "bnx2fc"])
-
-    return os.access("/sys/module/fcoe", os.X_OK)
-
-class fcoe(object):
-    """ FCoE utility class.
-
-        This class will automatically discover and connect to EDD configured
-        FCoE SAN's when the startup() method gets called. It can also be
-        used to manually configure FCoE SAN's through the addSan() method.
-
-        As this class needs to make sure certain things like starting fcoe
-        daemons and connecting to firmware discovered SAN's only happens once
-        and as it keeps a global list of all FCoE devices it is
-        implemented as a Singleton.
-    """
-
-    def __init__(self):
-        self.started = False
-        self.lldpadStarted = False
-        self.nics = []
-
-    # So that users can write fcoe() to get the singleton instance
-    def __call__(self):
-        return self
-
-    def _stabilize(self):
-        # I have no clue how long we need to wait, this ought to do the trick
-        time.sleep(10)
-        udev_settle()
-
-    def _startEDD(self):
-        rc = util.capture_output(["/usr/libexec/fcoe/fcoe_edd.sh", "-i"])
-        if not rc.startswith("NIC="):
-            log.info("No FCoE EDD info found: %s" % rc.rstrip())
-            return
-
-        (key, val) = rc.strip().split("=", 1)
-        #if val not in isys.getDeviceProperties():
-        #    log.error("Unknown FCoE NIC found in EDD: %s, ignoring" % val)
-        #    return
-
-        log.info("FCoE NIC found in EDD: %s" % val)
-        self.addSan(val, dcb=True, auto_vlan=True)
-
-    def startup(self):
-        if self.started:
-            return
-
-        if not has_fcoe():
-            return
-
-        self._startEDD()
-        self.started = True
-
-    def _startLldpad(self):
-        if self.lldpadStarted:
-            return
-
-        util.run_program(["lldpad", "-d"])
-        self.lldpadStarted = True
-
-    def addSan(self, nic, dcb=False, auto_vlan=True):
-        if not has_fcoe():
-            raise IOError, _("FCoE not available")
-
-        log.info("Activating FCoE SAN attached to %s, dcb: %s autovlan: %s" %
-                 (nic, dcb, auto_vlan))
-
-        util.run_program(["ip", "link", "set", nic, "up"])
-
-        if dcb:
-            self._startLldpad()
-            util.run_program(["dcbtool", "sc", nic, "dcb", "on"])
-            util.run_program(["dcbtool", "sc", nic, "app:fcoe",
-                                                "e:1", "a:1", "w:1"])
-            util.run_program(["fipvlan", "-c", "-s", "-f",
-                                               "'-fcoe'", nic])
-        else:
-            if auto_vlan:
-                # certain network configrations require the VLAN layer module:
-                util.run_program(["modprobe", "8021q"])
-                util.run_program(["fipvlan", '-c', '-s', '-f',
-                                                   "'-fcoe'",  nic])
-            else:
-                f = open("/sys/module/libfcoe/parameters/create", "w")
-                f.write(nic)
-                f.close()
-
-        self._stabilize()
-        self.nics.append((nic, dcb, auto_vlan))
-
-    def write(self):
-        if not self.nics:
-            return
-
-        if not os.path.isdir(ROOT_PATH + "/etc/fcoe"):
-            os.makedirs(ROOT_PATH + "/etc/fcoe", 0755)
-
-        for nic, dcb, auto_vlan in self.nics:
-            fd = os.open(ROOT_PATH + "/etc/fcoe/cfg-" + nic,
-                         os.O_RDWR | os.O_CREAT)
-            os.write(fd, '# Created by anaconda\n')
-            os.write(fd, '# Enable/Disable FCoE service at the Ethernet port\n')
-            os.write(fd, 'FCOE_ENABLE="yes"\n')
-            os.write(fd, '# Indicate if DCB service is required at the Ethernet port\n')
-            if dcb:
-                os.write(fd, 'DCB_REQUIRED="yes"\n')
-            else:
-                os.write(fd, 'DCB_REQUIRED="no"\n')
-            os.write(fd, '# Indicate if VLAN discovery should be handled by fcoemon\n')
-            if auto_vlan:
-                os.write(fd, 'AUTO_VLAN="yes"\n')
-            else:
-                os.write(fd, 'AUTO_VLAN="no"\n')
-            os.close(fd)
-
-        return
-
-# Create FCoE singleton
-fcoe = fcoe()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/storage/flags.py b/pyanaconda/storage/flags.py
deleted file mode 100644
index ed0e5dc..0000000
--- a/pyanaconda/storage/flags.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# flags.py
-#
-# Copyright (C) 2013  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): David Lehman <dlehman@redhat.com>
-#
-
-import shlex
-import selinux
-
-class Flags(object):
-    def __init__(self):
-        #
-        # mode of operation
-        #
-        self.testing = False
-        self.installer_mode = False
-
-        #
-        # minor modes (installer-specific)
-        #
-        self.automated_install = False
-        self.live_install = False
-        self.image_install = False
-
-        #
-        # enable/disable functionality
-        #
-        self.selinux = selinux.is_selinux_enabled()
-        self.multipath = True
-        self.dmraid = True
-        self.ibft = False
-        self.noiswmd = False
-
-        self.gfs2 = True
-        self.jfs = True
-        self.reiserfs = True
-
-        self.arm_platform = None
-
-        self.gpt = False
-
-        self.boot_cmdline = {}
-
-        self.update_from_boot_cmdline()
-
-    def get_boot_cmdline(self):
-        buf = open("/proc/cmdline").read().strip()
-        args = shlex.split(buf)
-        for arg in args:
-            (opt, equals, val) = arg.partition("=")
-            self.boot_cmdline[opt] = val
-
-    def update_from_boot_cmdline(self):
-        self.get_boot_cmdline()
-        if "nompath" in self.boot_cmdline:
-            self.multipath = False
-
-        if "nodmraid" in self.boot_cmdline:
-            self.dmraid = False
-
-        if "ibft" in self.boot_cmdline:
-            self.ibft = True
-
-        if "noiswmd" in self.boot_cmdline:
-            self.noiswmd = True
-
-    def update_from_anaconda_flags(self, anaconda_flags):
-        self.installer_mode = True
-        self.testing = anaconda_flags.testing
-        self.automated_install = anaconda_flags.automatedInstall
-        self.live_install = anaconda_flags.livecdInstall
-
-        self.selinux = anaconda_flags.selinux
-
-        self.gfs2 = "gfs2" in self.boot_cmdline
-        self.jfs = "jfs" in self.boot_cmdline
-        self.reiserfs = "reiserfs" in self.boot_cmdline
-
-        self.arm_platform = anaconda_flags.armPlatform
-        self.gpt = anaconda_flags.gpt
-
-
-flags = Flags()
diff --git a/pyanaconda/storage/formats/Makefile.am b/pyanaconda/storage/formats/Makefile.am
deleted file mode 100644
index 7ecaf07..0000000
--- a/pyanaconda/storage/formats/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# storage/formats/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@redhat.com>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storageformatsdir = $(pkgpyexecdir)/storage/formats
-storageformats_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/storage/formats/__init__.py b/pyanaconda/storage/formats/__init__.py
deleted file mode 100644
index 62bfb31..0000000
--- a/pyanaconda/storage/formats/__init__.py
+++ /dev/null
@@ -1,438 +0,0 @@
-# __init__.py
-# Entry point for anaconda storage formats subpackage.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-
-from pyanaconda.product import productName
-from pyanaconda.baseudev import udev_get_device
-from ..util import notify_kernel
-from ..util import get_sysfs_path_by_name
-from ..util import run_program
-from ..storage_log import log_method_call
-from ..errors import *
-from ..devicelibs.dm import dm_node_from_name
-from ..devicelibs.mdraid import md_node_from_name
-from ..udev import udev_device_get_major, udev_device_get_minor
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-device_formats = {}
-def register_device_format(fmt_class):
-    if not issubclass(fmt_class, DeviceFormat):
-        raise ValueError("arg1 must be a subclass of DeviceFormat")
-
-    device_formats[fmt_class._type] = fmt_class
-    log.debug("registered device format class %s as %s" % (fmt_class.__name__,
-                                                           fmt_class._type))
-
-default_fstypes = ["ext4", "ext3", "ext2"]
-if productName.startswith("Red Hat Enterprise Linux"):
-    default_fstypes.insert(0, "xfs")
-
-def get_default_filesystem_type():
-    for fstype in default_fstypes:
-        try:
-            supported = get_device_format_class(fstype).supported
-        except AttributeError:
-            supported = None
-
-        if supported:
-            return fstype
-
-    raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(default_fstypes))
-
-def getFormat(fmt_type, *args, **kwargs):
-    """ Return a DeviceFormat instance based on fmt_type and args.
-
-        Given a device format type and a set of constructor arguments,
-        return a DeviceFormat instance.
-
-        Return None if no suitable format class is found.
-
-        Arguments:
-
-            fmt_type -- the name of the format type (eg: 'ext3', 'swap')
-
-        Keyword Arguments:
-
-            The keyword arguments may vary according to the format type,
-            but here is the common set:
-
-            device -- path to the device on which the format resides
-            uuid -- the UUID of the (preexisting) formatted device
-            exists -- whether or not the format exists on the device            
-            
-    """
-    fmt_class = get_device_format_class(fmt_type)
-    fmt = None
-    if fmt_class:
-        fmt = fmt_class(*args, **kwargs)
-    try:
-        className = fmt.__class__.__name__
-    except AttributeError:
-        className = None
-    log.debug("getFormat('%s') returning %s instance" % (fmt_type, className))
-    return fmt
-
-def collect_device_format_classes():
-    """ Pick up all device format classes from this directory.
-
-        Note: Modules must call register_device_format(FormatClass) in
-              order for the format class to be picked up.
-    """
-    dir = os.path.dirname(__file__)
-    for module_file in os.listdir(dir):
-        # make sure we're not importing this module
-        if module_file.endswith(".py") and module_file != __file__:
-            mod_name = module_file[:-3]
-            # imputil is deprecated in python 2.6
-            try:
-                globals()[mod_name] = __import__(mod_name, globals(), locals(), [], -1)
-            except ImportError:
-                log.error("import of device format module '%s' failed" % mod_name)
-                from traceback import format_exc
-                log.debug(format_exc())
-
-def get_device_format_class(fmt_type):
-    """ Return an appropriate format class based on fmt_type. """
-    if not device_formats:
-        collect_device_format_classes()
-
-    fmt = device_formats.get(fmt_type)
-    if not fmt:
-        for fmt_class in device_formats.values():
-            if fmt_type and fmt_type == fmt_class._name:
-                fmt = fmt_class
-                break
-            elif fmt_type in fmt_class._udevTypes:
-                fmt = fmt_class
-                break
-
-    # default to no formatting, AKA "Unknown"
-    if not fmt:
-        fmt = DeviceFormat
-
-    return fmt
-
-class DeviceFormat(object):
-    """ Generic device format. """
-    _type = None
-    _name = "Unknown"
-    _udevTypes = []
-    partedFlag = None
-    partedSystem = None
-    _formattable = False                # can be formatted
-    _supported = False                  # is supported
-    _linuxNative = False                # for clearpart
-    _packages = []                      # required packages
-    _services = []                      # required services
-    _resizable = False                  # can be resized
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _dump = False
-    _check = False
-    _hidden = False                     # hide devices with this formatting?
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-        """
-        self.device = kwargs.get("device")
-        self.uuid = kwargs.get("uuid")
-        self.exists = kwargs.get("exists")
-        self.options = kwargs.get("options")
-        self._majorminor = None
-
-        # don't worry about existence if this is a DeviceFormat instance
-        #if self.__class__ is DeviceFormat:
-        #    self.exists = True
-
-    def __repr__(self):
-        s = ("%(classname)s instance (%(id)s) --\n"
-             "  type = %(type)s  name = %(name)s  status = %(status)s\n"
-             "  device = %(device)s  uuid = %(uuid)s  exists = %(exists)s\n"
-             "  options = %(options)s  supported = %(supported)s"
-             "  formattable = %(format)s  resizable = %(resize)s\n" %
-             {"classname": self.__class__.__name__, "id": "%#x" % id(self),
-              "type": self.type, "name": self.name, "status": self.status,
-              "device": self.device, "uuid": self.uuid, "exists": self.exists,
-              "options": self.options, "supported": self.supported,
-              "format": self.formattable, "resize": self.resizable})
-        return s
-
-    @property
-    def _existence_str(self):
-        exist = "existing"
-        if not self.exists:
-            exist = "non-existent"
-        return exist
-
-    @property
-    def desc(self):
-        return str(self.type)
-
-    def __str__(self):
-        return "%s %s" % (self._existence_str, self.desc)
-
-    @property
-    def dict(self):
-        d = {"type": self.type, "name": self.name, "device": self.device,
-             "uuid": self.uuid, "exists": self.exists,
-             "options": self.options, "supported": self.supported,
-             "resizable": self.resizable}
-        return d
-
-    def _setOptions(self, options):
-        self._options = options
-
-    def _getOptions(self):
-        return self._options
-
-    options = property(_getOptions, _setOptions)
-
-    def _setDevice(self, devspec):
-        if devspec and not devspec.startswith("/"):
-            raise ValueError("device must be a fully qualified path")
-        self._device = devspec
-
-    def _getDevice(self):
-        return self._device
-
-    device = property(lambda f: f._getDevice(),
-                      lambda f,d: f._setDevice(d),
-                      doc="Full path the device this format occupies")
-
-    @property
-    def name(self):
-        if self._name:
-            name = self._name
-        else:
-            name = self.type
-        return name
-
-    @property
-    def type(self):
-        return self._type
-
-    def probe(self):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-    def notifyKernel(self):
-        log_method_call(self, device=self.device,
-                        type=self.type)
-        if not self.device:
-            return
-
-        if self.device.startswith("/dev/mapper/"):
-            try:
-                name = dm_node_from_name(os.path.basename(self.device))
-            except DMError:
-                log.warning("failed to get dm node for %s" % self.device)
-                return
-        elif self.device.startswith("/dev/md/"):
-            try:
-                name = md_node_from_name(os.path.basename(self.device))
-            except MDRaidError:
-                log.warning("failed to get md node for %s" % self.device)
-                return
-        else:
-            name = self.device
-
-        path = get_sysfs_path_by_name(name)
-        try:
-            notify_kernel(path, action="change")
-        except (ValueError, IOError) as e:
-            log.warning("failed to notify kernel of change: %s" % e)
-
-    def cacheMajorminor(self):
-        """ Cache the value of self.majorminor.
-
-            Once a device node of this format's device disappears (for instance
-            after a teardown), it is no longer possible to figure out the value
-            of self.majorminor pseudo-unique string. Call this method before
-            that happens for caching this.
-        """
-        self._majorminor = None
-        try:
-            self.majorminor # this does the caching
-        except StorageError:
-            # entirely possible there's no majorminor, for instance an
-            # LVMVolumeGroup has got no device node and no sysfs path.  In this
-            # case obviously, calling majorminor of this object later raises an
-            # exception.
-            pass
-        return self._majorminor
-
-    def create(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        # allow late specification of device path
-        device = kwargs.get("device")
-        if device:
-            self.device = device
-
-        if not os.path.exists(self.device):
-            raise FormatCreateError("invalid device specification", self.device)
-
-    def destroy(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        try:
-            rc = run_program(["wipefs", "-a", self.device])
-        except OSError as e:
-            err = str(e)
-        else:
-            err = ""
-            if rc:
-                err = str(rc)
-
-        if err:
-            msg = "error wiping old signatures from %s: %s" % (self.device, err)
-            raise FormatDestroyError(msg)
-
-        self.exists = False
-
-    def setup(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-        if not self.exists:
-            raise FormatSetupError("format has not been created")
-
-        if self.status:
-            return
-
-        # allow late specification of device path
-        device = kwargs.get("device")
-        if device:
-            self.device = device
-
-        if not self.device or not os.path.exists(self.device):
-            raise FormatSetupError("invalid device specification")
-
-    def teardown(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-    @property
-    def status(self):
-        return (self.exists and
-                self.__class__ is not DeviceFormat and
-                isinstance(self.device, str) and
-                self.device and 
-                os.path.exists(self.device))
-
-    @property
-    def formattable(self):
-        """ Can we create formats of this type? """
-        return self._formattable
-
-    @property
-    def supported(self):
-        """ Is this format a supported type? """
-        return self._supported
-
-    @property
-    def packages(self):
-        """ Packages required to manage formats of this type. """
-        return self._packages
-
-    @property
-    def services(self):
-        """ Services required to manage formats of this type. """
-        return self._services
-
-    @property
-    def resizable(self):
-        """ Can formats of this type be resized? """
-        return self._resizable and self.exists
-
-    @property
-    def linuxNative(self):
-        """ Is this format type native to linux? """
-        return self._linuxNative
-
-    @property
-    def mountable(self):
-        """ Is this something we can mount? """
-        return False
-
-    @property
-    def dump(self):
-        """ Whether or not this format will be dumped by dump(8). """
-        return self._dump
-
-    @property
-    def check(self):
-        """ Whether or not this format is checked on boot. """
-        return self._check
-
-    @property
-    def maxSize(self):
-        """ Maximum size (in MB) for this format type. """
-        return self._maxSize
-
-    @property
-    def minSize(self):
-        """ Minimum size (in MB) for this format type. """
-        return self._minSize
-
-    @property
-    def hidden(self):
-        """ Whether devices with this formatting should be hidden in UIs. """
-        return self._hidden
-
-    @property
-    def majorminor(self):
-        """A string suitable for using as a pseudo-unique ID in kickstart."""
-        if not self._majorminor:
-            # If this is a device-mapper device, we have to get the DM node and
-            # build the sysfs path from that.
-            try:
-                device = dm_node_from_name(os.path.basename(self.device))
-            except DMError:
-                device = self.device
-
-            try:
-                sysfs_path = get_sysfs_path_by_name(device)
-            except RuntimeError:
-                raise StorageError("DeviceFormat.majorminor: "
-                                   "can not get majorminor for '%s'" % device)
-            dev = udev_get_device(sysfs_path[4:])
-
-            self._majorminor = "%03d%03d" %\
-                (udev_device_get_major(dev), udev_device_get_minor(dev))
-        return self._majorminor
-
-collect_device_format_classes()
diff --git a/pyanaconda/storage/formats/biosboot.py b/pyanaconda/storage/formats/biosboot.py
deleted file mode 100644
index c3aef8d..0000000
--- a/pyanaconda/storage/formats/biosboot.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# biosboot.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2011  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-from parted import PARTITION_BIOS_GRUB
-
-from ..errors import *
-from .. import platform
-from . import DeviceFormat, register_device_format
-
-class BIOSBoot(DeviceFormat):
-    """ BIOS boot partition for GPT disklabels. """
-    _type = "biosboot"
-    _name = "BIOS Boot"
-    _udevTypes = []
-    partedFlag = PARTITION_BIOS_GRUB
-    _formattable = True                 # can be formatted
-    _linuxNative = True                 # for clearpart
-    _maxSize = 2                        # maximum size in MB
-    _minSize = 0.5                      # minimum size in MB
-
-    def __init__(self, *args, **kwargs):
-        """ Create a BIOSBoot instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                exists -- indicates whether this is an existing format
-
-        """
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-    @property
-    def status(self):
-        return False
-
-    @property
-    def supported(self):
-        return isinstance(platform.platform, platform.X86)
-
-register_device_format(BIOSBoot)
-
diff --git a/pyanaconda/storage/formats/disklabel.py b/pyanaconda/storage/formats/disklabel.py
deleted file mode 100644
index 018adf4..0000000
--- a/pyanaconda/storage/formats/disklabel.py
+++ /dev/null
@@ -1,443 +0,0 @@
-# disklabel.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-import copy
-
-from ..storage_log import log_method_call
-import parted
-import _ped
-from ..errors import *
-from .. import arch
-from ..flags import flags
-from ..udev import udev_settle
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class DiskLabel(DeviceFormat):
-    """ Disklabel """
-    _type = "disklabel"
-    _name = "partition table"
-    _formattable = True                # can be formatted
-    _supported = False                 # is supported
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DiskLabel instance.
-
-            Keyword Arguments:
-
-                labelType -- type of disklabel to create
-                device -- path to the underlying device
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        if not self.exists:
-            self._labelType = kwargs.get("labelType", "msdos")
-        else:
-            self._labelType = ""
-
-        self._size = None
-
-        self._partedDevice = None
-        self._partedDisk = None
-        self._origPartedDisk = None
-        self._alignment = None
-        self._endAlignment = None
-
-        if self.partedDevice:
-            # set up the parted objects and raise exception on failure
-            self._origPartedDisk = self.partedDisk.duplicate()
-
-    def __deepcopy__(self, memo):
-        """ Create a deep copy of a Disklabel instance.
-
-            We can't do copy.deepcopy on parted objects, which is okay.
-            For these parted objects, we just do a shallow copy.
-        """
-        new = self.__class__.__new__(self.__class__)
-        memo[id(self)] = new
-        shallow_copy_attrs = ('_partedDevice', '_alignment', '_endAlignment')
-        duplicate_attrs = ('_partedDisk', '_origPartedDisk')
-        for (attr, value) in self.__dict__.items():
-            if attr in shallow_copy_attrs:
-                setattr(new, attr, copy.copy(value))
-            elif attr in duplicate_attrs:
-                setattr(new, attr, value.duplicate())
-            else:
-                setattr(new, attr, copy.deepcopy(value, memo))
-
-        return new
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        if flags.testing:
-            return s
-        s += ("  type = %(type)s  partition count = %(count)s"
-              "  sectorSize = %(sectorSize)s\n"
-              "  align_offset = %(offset)s  align_grain = %(grain)s\n"
-              "  partedDisk = %(disk)s\n"
-              "  origPartedDisk = %(orig_disk)r\n"
-              "  partedDevice = %(dev)s\n" %
-              {"type": self.labelType, "count": len(self.partitions),
-               "sectorSize": self.partedDevice.sectorSize,
-               "offset": self.alignment.offset,
-               "grain": self.alignment.grainSize,
-               "disk": self.partedDisk, "orig_disk": self._origPartedDisk,
-               "dev": self.partedDevice})
-        return s
-
-    @property
-    def desc(self):
-        return "%s %s" % (self.labelType, self.type)
-
-    @property
-    def dict(self):
-        d = super(DiskLabel, self).dict
-        if flags.testing:
-            return d
-
-        d.update({"labelType": self.labelType,
-                  "partitionCount": len(self.partitions),
-                  "sectorSize": self.partedDevice.sectorSize,
-                  "offset": self.alignment.offset,
-                  "grainSize": self.alignment.grainSize})
-        return d
-
-    def resetPartedDisk(self):
-        """ Set this instance's partedDisk to reflect the disk's contents. """
-        log_method_call(self, device=self.device)
-        self._partedDisk = self._origPartedDisk
-
-    def freshPartedDisk(self):
-        """ Return a new, empty parted.Disk instance for this device. """
-        log_method_call(self, device=self.device, labelType=self._labelType)
-        return parted.freshDisk(device=self.partedDevice, ty=self._labelType)
-
-    @property
-    def partedDisk(self):
-        if not self._partedDisk:
-            if self.exists:
-                try:
-                    self._partedDisk = parted.Disk(device=self.partedDevice)
-                except (_ped.DiskLabelException, _ped.IOException,
-                        NotImplementedError) as e:
-                    raise InvalidDiskLabelError()
-
-                if self._partedDisk.type == "loop":
-                    # When the device has no partition table but it has a FS,
-                    # it will be created with label type loop.  Treat the
-                    # same as if the device had no label (cause it really
-                    # doesn't).
-                    raise InvalidDiskLabelError()
-
-                # here's where we correct the ctor-supplied disklabel type for
-                # preexisting disklabels if the passed type was wrong
-                self._labelType = self._partedDisk.type
-            else:
-                self._partedDisk = self.freshPartedDisk()
-
-            # turn off cylinder alignment
-            if self._partedDisk.isFlagAvailable(parted.DISK_CYLINDER_ALIGNMENT):
-                self._partedDisk.unsetFlag(parted.DISK_CYLINDER_ALIGNMENT)
-
-            # Set the boot flag on the GPT PMBR, this helps some BIOS systems boot
-            if self._partedDisk.isFlagAvailable(parted.DISK_GPT_PMBR_BOOT):
-                # MAC can boot as EFI or as BIOS, neither should have PMBR boot set
-                if arch.isEfi() or arch.isMactel():
-                    self._partedDisk.unsetFlag(parted.DISK_GPT_PMBR_BOOT)
-                    log.debug("Clear pmbr_boot on %s" % (self._partedDisk,))
-                else:
-                    self._partedDisk.setFlag(parted.DISK_GPT_PMBR_BOOT)
-                    log.debug("Set pmbr_boot on %s" % (self._partedDisk,))
-            else:
-                log.debug("Did not change pmbr_boot on %s" % (self._partedDisk,))
-
-        return self._partedDisk
-
-    @property
-    def partedDevice(self):
-        if not self._partedDevice and self.device:
-            if os.path.exists(self.device):
-                # We aren't guaranteed to be able to get a device.  In
-                # particular, built-in USB flash readers show up as devices but
-                # do not always have any media present, so parted won't be able
-                # to find a device.
-                try:
-                    self._partedDevice = parted.Device(path=self.device)
-                except (_ped.IOException, _ped.DeviceException) as e:
-                    log.error("DiskLabel.partedDevice: Parted exception: %s" % e)
-            else:
-                log.info("DiskLabel.partedDevice: %s does not exist" % self.device)
-
-        if not self._partedDevice:
-            log.info("DiskLabel.partedDevice returning None")
-        return self._partedDevice
-
-    @property
-    def labelType(self):
-        """ The disklabel type (eg: 'gpt', 'msdos') """
-        try:
-            lt = self.partedDisk.type
-        except Exception:
-            lt = self._labelType
-        return lt
-
-    @property
-    def name(self):
-        return "%s (%s)" % (self._name, self.labelType.upper())
-
-    @property
-    def size(self):
-        size = self._size
-        if not size:
-            try:
-                size = self.partedDevice.getSize(unit="MB")
-            except Exception:
-                size = 0
-
-        return size
-
-    @property
-    def status(self):
-        """ Device status. """
-        return False
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise DeviceFormatError("format has not been created")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise DeviceFormatError("format has not been created")
-
-    def create(self, *args, **kwargs):
-        """ Create the device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if self.exists:
-            raise DeviceFormatError("format already exists")
-
-        if self.status:
-            raise DeviceFormatError("device exists and is active")
-
-        DeviceFormat.create(self, *args, **kwargs)
-
-        # We're relying on someone having called resetPartedDisk -- we
-        # could ensure a fresh disklabel by setting self._partedDisk to
-        # None right before calling self.commit(), but that might hide
-        # other problems.
-        self.commit()
-        self.exists = True
-
-    def destroy(self, *args, **kwargs):
-        """ Wipe the disklabel from the device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise DeviceFormatError("format does not exist")
-
-        if not os.access(self.device, os.W_OK):
-            raise DeviceFormatError("device path does not exist")
-
-        self.partedDevice.clobber()
-        self.exists = False
-
-    def commit(self):
-        """ Commit the current partition table to disk and notify the OS. """
-        log_method_call(self, device=self.device,
-                        numparts=len(self.partitions))
-        try:
-            self.partedDisk.commit()
-        except parted.DiskException as msg:
-            raise DiskLabelCommitError(msg)
-        else:
-            udev_settle()
-
-    def commitToDisk(self):
-        """ Commit the current partition table to disk. """
-        log_method_call(self, device=self.device,
-                        numparts=len(self.partitions))
-        try:
-            self.partedDisk.commitToDevice()
-        except parted.DiskException as msg:
-            raise DiskLabelCommitError(msg)
-
-    def addPartition(self, *args, **kwargs):
-        partition = kwargs.get("partition", None)
-        if not partition:
-            partition = args[0]
-        geometry = partition.geometry
-        constraint = kwargs.get("constraint", None)
-        if not constraint and len(args) > 1:
-            constraint = args[1]
-        elif not constraint:
-            constraint = parted.Constraint(exactGeom=geometry)
-
-        new_partition = parted.Partition(disk=self.partedDisk,
-                                         type=partition.type,
-                                         geometry=geometry)
-        self.partedDisk.addPartition(partition=new_partition,
-                                     constraint=constraint)
-
-    def removePartition(self, partition):
-        self.partedDisk.removePartition(partition)
-
-    @property
-    def extendedPartition(self):
-        try:
-            extended = self.partedDisk.getExtendedPartition()
-        except Exception:
-            extended = None
-        return extended
-
-    @property
-    def logicalPartitions(self):
-        try:
-            logicals = self.partedDisk.getLogicalPartitions()
-        except Exception:
-            logicals = []
-        return logicals
-
-    @property
-    def firstPartition(self):
-        try:
-            part = self.partedDisk.getFirstPartition()
-        except Exception:
-            part = None
-        return part
-
-    @property
-    def partitions(self):
-        try:
-            parts = self.partedDisk.partitions
-        except Exception:
-            parts = []
-            if flags.testing:
-                sys_block_root = "/sys/class/block/"
-
-                # FIXME: /dev/mapper/foo won't work without massaging
-                disk_name = self.device.split("/")[-1]
-
-                disk_root = sys_block_root + disk_name
-                parts = [n for n in os.listdir(disk_root) if n.startswith(disk_name)]
-        return parts
-
-    @property
-    def alignment(self):
-        """ Alignment requirements for this device. """
-        if not self._alignment:
-            try:
-                disklabel_alignment = self.partedDisk.partitionAlignment
-            except _ped.CreateException:
-                disklabel_alignment = parted.Alignment(offset=0, grainSize=1)
-
-            try:
-                optimum_device_alignment = self.partedDevice.optimumAlignment
-            except _ped.CreateException:
-                optimum_device_alignment = None
-
-            try:
-                minimum_device_alignment = self.partedDevice.minimumAlignment
-            except _ped.CreateException:
-                minimum_device_alignment = None
-
-            try:
-                a = optimum_device_alignment.intersect(disklabel_alignment)
-            except (ArithmeticError, AttributeError):
-                try:
-                    a = minimum_device_alignment.intersect(disklabel_alignment)
-                except (ArithmeticError, AttributeError):
-                    a = disklabel_alignment
-
-            self._alignment = a
-
-        return self._alignment
-
-    @property
-    def endAlignment(self):
-        if not self._endAlignment:
-            self._endAlignment = parted.Alignment(
-                                        offset = self.alignment.offset - 1,
-                                        grainSize = self.alignment.grainSize)
-
-        return self._endAlignment
-
-    @property
-    def free(self):
-        def read_int_from_sys(path):
-            return int(open(path).readline().strip())
-
-        try:
-            free = sum([f.getSize()
-                        for f in self.partedDisk.getFreeSpacePartitions()])
-        except Exception:
-            sys_block_root = "/sys/class/block/"
-
-            # FIXME: /dev/mapper/foo won't work without massaging
-            disk_name = self.device.split("/")[-1]
-
-            disk_root = sys_block_root + disk_name
-            disk_length = read_int_from_sys("%s/size" % disk_root)
-            sector_size = read_int_from_sys("%s/queue/logical_block_size" % disk_root)
-            partition_names = [n for n in os.listdir(disk_root) if n.startswith(disk_name)]
-            used_sectors = 0
-            for partition_name in partition_names:
-                partition_root = sys_block_root + partition_name
-                partition_length = read_int_from_sys("%s/size" % partition_root)
-                used_sectors += partition_length
-
-            free = ((disk_length - used_sectors) * sector_size) / (1024.0 * 1024.0)
-
-        return free
-
-    @property
-    def magicPartitionNumber(self):
-        """ Number of disklabel-type-specific special partition. """
-        if self.labelType == "mac":
-            return 1
-        elif self.labelType == "sun":
-            return 3
-        else:
-            return 0
-
-register_device_format(DiskLabel)
-
diff --git a/pyanaconda/storage/formats/dmraid.py b/pyanaconda/storage/formats/dmraid.py
deleted file mode 100644
index f37b2d3..0000000
--- a/pyanaconda/storage/formats/dmraid.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# dmraid.py
-# dmraid device formats
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-from ..storage_log import log_method_call
-from ..flags import flags
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class DMRaidMember(DeviceFormat):
-    """ A dmraid member disk. """
-    _type = "dmraidmember"
-    _name = "dm-raid member device"
-    # XXX This looks like trouble.
-    #
-    #     Maybe a better approach is a RaidMember format with subclass
-    #     for MDRaidMember, letting all *_raid_member types fall through
-    #     to the generic RaidMember format, which is basically read-only.
-    #
-    #     One problem that presents is the possibility of someone passing
-    #     a dmraid member to the MDRaidArrayDevice constructor.
-    _udevTypes = ["adaptec_raid_member", "ddf_raid_member",
-                 "hpt37x_raid_member", "hpt45x_raid_member",
-                 "isw_raid_member",
-                 "jmicron_raid_member", "lsi_mega_raid_member",
-                 "nvidia_raid_member", "promise_fasttrack_raid_member",
-                 "silicon_medley_raid_member", "via_raid_member"]
-    _formattable = False                # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = False                # for clearpart
-    _packages = ["dmraid"]              # required packages
-    _resizable = False                  # can be resized
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _hidden = True                      # hide devices with this formatting?
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-            On initialization this format is like DeviceFormat
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        # Initialize the attribute that will hold the block object.
-        self._raidmem = None
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        s += ("  raidmem = %(raidmem)r" % {"raidmem": self.raidmem})
-        return s
-
-    def _getRaidmem(self):
-        return self._raidmem
-
-    def _setRaidmem(self, raidmem):
-        self._raidmem = raidmem
-
-    raidmem = property(lambda d: d._getRaidmem(),
-                       lambda d,r: d._setRaidmem(r))
-
-    def create(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise DMRaidMemberError("creation of dmraid members is non-sense")
-
-    def destroy(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise DMRaidMemberError("destruction of dmraid members is non-sense")
-
-
-if not flags.noiswmd:
-    DMRaidMember._udevTypes.remove("isw_raid_member")
-
-# The anaconda cmdline has not been parsed yet when we're first imported,
-# so we can not use flags.dmraid here
-if not flags.dmraid:
-    DMRaidMember._udevTypes = []
-
-register_device_format(DMRaidMember)
-
diff --git a/pyanaconda/storage/formats/fs.py b/pyanaconda/storage/formats/fs.py
deleted file mode 100644
index b472e87..0000000
--- a/pyanaconda/storage/formats/fs.py
+++ /dev/null
@@ -1,1433 +0,0 @@
-# filesystems.py
-# Filesystem classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#                    David Cantrell <dcantrell@redhat.com>
-#
-
-""" Filesystem classes for use by anaconda.
-
-    TODO:
-        - bug 472127: allow creation of tmpfs filesystems (/tmp, /var/tmp, &c)
-"""
-import math
-import os
-import sys
-import tempfile
-import selinux
-
-from ..errors import *
-from . import DeviceFormat, register_device_format
-from .. import util
-from .. import platform
-from ..flags import flags
-from parted import fileSystemType
-from ..storage_log import log_method_call
-
-import logging
-log = logging.getLogger("storage")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-try:
-    lost_and_found_context = selinux.matchpathcon("/lost+found", 0)[1]
-except OSError:
-    lost_and_found_context = None
-
-# these are for converting to/from SI for ntfsresize
-mb = 1000 * 1000.0
-mib = 1024 * 1024.0
-
-fs_configs = {}
-
-def get_kernel_filesystems():
-    fs_list = []
-    for line in open("/proc/filesystems").readlines():
-        fs_list.append(line.split()[-1])
-    return fs_list
-
-global kernel_filesystems
-kernel_filesystems = get_kernel_filesystems()
-
-def fsConfigFromFile(config_file):
-    """ Generate a set of attribute name/value pairs with which a
-        filesystem type can be defined.
-
-        The following config file would define a filesystem identical to
-        the static Ext3FS class definition:
-
-            type = ext3
-            mkfs = "mke2fs"
-            resizefs = "resize2fs"
-            labelfs = "e2label"
-            fsck = "e2fsck"
-            packages = ["e2fsprogs"]
-            formattable = True
-            supported = True
-            resizable = True
-            linuxNative = True
-            maxSize = 8 * 1024 * 1024
-            minSize = 0
-            defaultFormatOptions = "-t ext3"
-            defaultMountOptions = "defaults"
-
-    """
-    # XXX NOTUSED
-    lines = open(config_file).readlines()
-    fs_attrs = {}
-    for line in lines:
-        (key, value) = [t.strip() for t in line.split("=")]
-        if not hasattr(FS, "_" + key):
-            print "invalid key: %s" % key
-            continue
-
-        fs_attrs[key] = value
-
-    if not fs_attrs.has_key("type"):
-        raise ValueError, _("filesystem configuration missing a type")
-
-    # XXX what's the policy about multiple configs for a given type?
-    fs_configs[fs_attrs['type']] = fs_attrs
-
-class FS(DeviceFormat):
-    """ Filesystem class. """
-    _type = "Abstract Filesystem Class"  # fs type name
-    _mountType = None                    # like _type but for passing to mount
-    _name = None
-    _mkfs = ""                           # mkfs utility
-    _modules = []                        # kernel modules required for support
-    _resizefs = ""                       # resize utility
-    _labelfs = ""                        # labeling utility
-    _fsck = ""                           # fs check utility
-    _fsckErrors = {}                     # fs check command error codes & msgs
-    _infofs = ""                         # fs info utility
-    _defaultFormatOptions = []           # default options passed to mkfs
-    _defaultMountOptions = ["defaults"]  # default options passed to mount
-    _defaultLabelOptions = []
-    _defaultCheckOptions = []
-    _defaultInfoOptions = []
-    _existingSizeFields = []
-    _fsProfileSpecifier = None           # mkfs option specifying fsprofile
-
-    def __init__(self, *args, **kwargs):
-        """ Create a FS instance.
-
-            Keyword Args:
-
-                device -- path to the device containing the filesystem
-                mountpoint -- the filesystem's mountpoint
-                label -- the filesystem label
-                uuid -- the filesystem UUID
-                mountopts -- mount options for the filesystem
-                size -- the filesystem's size in MiB
-                exists -- indicates whether this is an existing filesystem
-                
-        """
-        if self.__class__ is FS:
-            raise TypeError("FS is an abstract class.")
-
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.mountpoint = kwargs.get("mountpoint")
-        self.mountopts = kwargs.get("mountopts")
-        self.label = kwargs.get("label")
-        self.fsprofile = kwargs.get("fsprofile")
-
-        # filesystem size does not necessarily equal device size
-        self._size = kwargs.get("size", 0)
-        self._minInstanceSize = None    # min size of this FS instance
-        self._mountpoint = None     # the current mountpoint when mounted
-        if self.exists:
-            self._size = self._getExistingSize()
-            foo = self.minSize      # force calculation of minimum size
-
-        self._targetSize = self._size
-
-        if self.supported:
-            self.loadModule()
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        s += ("  mountpoint = %(mountpoint)s  mountopts = %(mountopts)s\n"
-              "  label = %(label)s  size = %(size)s"
-              "  targetSize = %(targetSize)s\n" %
-              {"mountpoint": self.mountpoint, "mountopts": self.mountopts,
-               "label": self.label, "size": self._size,
-               "targetSize": self.targetSize})
-        return s
-
-    @property
-    def desc(self):
-        s = "%s filesystem" % self.type
-        if self.mountpoint:
-            s += " mounted at %s" % self.mountpoint
-        return s
-
-    @property
-    def dict(self):
-        d = super(FS, self).dict
-        d.update({"mountpoint": self.mountpoint, "size": self._size,
-                  "label": self.label, "targetSize": self.targetSize,
-                  "mountable": self.mountable})
-        return d
-
-    def _setTargetSize(self, newsize):
-        """ Set a target size for this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if newsize is None:
-            # unset any outstanding resize request
-            self._targetSize = self._size
-            return
-
-        if not self.minSize <= newsize < self.maxSize:
-            raise ValueError("invalid target size request")
-
-        self._targetSize = newsize
-
-    def _getTargetSize(self):
-        """ Get this filesystem's target size. """
-        return self._targetSize
-
-    targetSize = property(_getTargetSize, _setTargetSize,
-                          doc="Target size for this filesystem")
-
-    def _getSize(self):
-        """ Get this filesystem's size. """
-        size = self._size
-        if self.resizable and self.targetSize != size:
-            size = self.targetSize
-        return size
-
-    size = property(_getSize, doc="This filesystem's size, accounting "
-                                  "for pending changes")
-
-    def _getExistingSize(self):
-        """ Determine the size of this filesystem.  Filesystem must
-            exist.  Each filesystem varies, but the general procedure
-            is to run the filesystem dump or info utility and read
-            the block size and number of blocks for the filesystem
-            and compute megabytes from that.
-
-            The loop that reads the output from the infofsProg is meant
-            to be simple, but take in to account variations in output.
-            The general procedure:
-                1) Capture output from infofsProg.
-                2) Iterate over each line of the output:
-                       a) Trim leading and trailing whitespace.
-                       b) Break line into fields split on ' '
-                       c) If line begins with any of the strings in
-                          _existingSizeFields, start at the end of
-                          fields and take the first one that converts
-                          to a long.  Store this in the values list.
-                       d) Repeat until the values list length equals
-                          the _existingSizeFields length.
-                3) If the length of the values list equals the length
-                   of _existingSizeFields, compute the size of this
-                   filesystem by multiplying all of the values together
-                   to get bytes, then convert to megabytes.  Return
-                   this value.
-                4) If we were unable to capture all fields, return 0.
-
-            The caller should catch exceptions from this method.  Any
-            exception raised indicates a need to change the fields we
-            are looking for, the command to run and arguments, or
-            something else.  If you catch an exception from this method,
-            assume the filesystem cannot be resized.
-        """
-        size = self._size
-
-        if self.infofsProg and self.exists and not size and \
-           util.find_program_in_path(self.infofsProg):
-            try:
-                values = []
-                argv = self._defaultInfoOptions + [ self.device ]
-
-                buf = util.capture_output([self.infofsProg] + argv)
-
-                for line in buf.splitlines():
-                    found = False
-
-                    line = line.strip()
-                    tmp = line.split(' ')
-                    tmp.reverse()
-
-                    for field in self._existingSizeFields:
-                        if line.startswith(field):
-                            for subfield in tmp:
-                                try:
-                                    values.append(long(subfield))
-                                    found = True
-                                    break
-                                except ValueError:
-                                    continue
-
-                        if found:
-                            break
-
-                    if len(values) == len(self._existingSizeFields):
-                        break
-
-                if len(values) != len(self._existingSizeFields):
-                    return 0
-
-                size = 1
-                for value in values:
-                    size *= value
-
-                # report current size as megabytes
-                size = math.floor(size / 1024.0 / 1024.0)
-            except Exception as e:
-                log.error("failed to obtain size of filesystem on %s: %s"
-                          % (self.device, e))
-
-        return size
-
-    @property
-    def currentSize(self):
-        """ The filesystem's current actual size. """
-        size = 0
-        if self.exists:
-            size = self._size
-        return float(size)
-
-    @property
-    def free(self):
-        free = 0
-        if self.exists:
-            if self.currentSize and self.minSize and \
-               self.currentSize != self.minSize:
-                free = int(max(0, self.currentSize - self.minSize)) # truncate
-
-        return free
-
-    def _getFormatOptions(self, options=None):
-        argv = []
-        if options and isinstance(options, list):
-            argv.extend(options)
-        argv.extend(self.defaultFormatOptions)
-        if self._fsProfileSpecifier and self.fsprofile:
-            argv.extend([self._fsProfileSpecifier, self.fsprofile])
-        argv.append(self.device)
-        return argv
-    
-    def doFormat(self, *args, **kwargs):
-        """ Create the filesystem.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                options -- list of options to pass to mkfs
-
-        """
-        log_method_call(self, type=self.mountType, device=self.device,
-                        mountpoint=self.mountpoint)
-
-        options = kwargs.get("options")
-
-        if self.exists:
-            raise FormatCreateError("filesystem already exists", self.device)
-
-        if not self.formattable:
-            return
-
-        if not self.mkfsProg:
-            return
-
-        if self.exists:
-            return
-
-        if not os.path.exists(self.device):
-            raise FormatCreateError("device does not exist", self.device)
-
-        argv = self._getFormatOptions(options=options)
-
-        try:
-            ret = util.run_program([self.mkfsProg] + argv)
-        except OSError as e:
-            raise FormatCreateError(e, self.device)
-
-        if ret:
-            raise FormatCreateError("format failed: %s" % ret.rc, self.device)
-
-        self.exists = True
-        self.notifyKernel()
-
-        if self.label:
-            self.writeLabel(self.label)
-
-    @property
-    def resizeArgs(self):
-        argv = [self.device, "%d" % (self.targetSize,)]
-        return argv
-
-    def doResize(self, *args, **kwargs):
-        """ Resize this filesystem to new size @newsize.
-
-            Arguments:
-
-                None
-        """
-
-        if not self.exists:
-            raise FSResizeError("filesystem does not exist", self.device)
-
-        if not self.resizable:
-            raise FSResizeError("filesystem not resizable", self.device)
-
-        if self.targetSize == self.currentSize:
-            return
-
-        if not self.resizefsProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSResizeError("device does not exist", self.device)
-
-        self.doCheck()
-
-        # The first minimum size can be incorrect if the fs was not
-        # properly unmounted. After doCheck the minimum size will be correct
-        # so run the check one last time and bump up the size if it was too
-        # small.
-        self._minInstanceSize = None
-        if self.targetSize < self.minSize:
-            self.targetSize = self.minSize
-            log.info("Minimum size changed, setting targetSize on %s to %s" \
-                     % (self.device, self.targetSize))
-        try:
-            ret = util.run_program([self.resizefsProg] + self.resizeArgs)
-        except OSError as e:
-            raise FSResizeError(e, self.device)
-
-        if ret:
-            raise FSResizeError("resize failed: %s" % ret, self.device)
-
-        self.doCheck()
-
-        # XXX must be a smarter way to do this
-        self._size = self.targetSize
-        self.notifyKernel()
-
-    def _getCheckArgs(self):
-        argv = []
-        argv.extend(self.defaultCheckOptions)
-        argv.append(self.device)
-        return argv
-
-    def _fsckFailed(self, rc):
-        return False
-
-    def _fsckErrorMessage(self, rc):
-        return _("Unknown return code: %d.") % (rc,)
-
-    def doCheck(self):
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.fsckProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        try:
-            ret = util.run_program([self.fsckProg] + self._getCheckArgs())
-        except OSError as e:
-            raise FSError("filesystem check failed: %s" % e)
-
-        if self._fsckFailed(ret):
-            hdr = _("%(type)s filesystem check failure on %(device)s: ") % \
-                    {"type": self.type, "device": self.device}
-
-            msg = self._fsckErrorMessage(ret)
-            raise FSError(hdr + msg)
-
-    def loadModule(self):
-        """Load whatever kernel module is required to support this filesystem."""
-        global kernel_filesystems
-
-        if not self._modules or self.mountType in kernel_filesystems:
-            return
-
-        for module in self._modules:
-            try:
-                rc = util.run_program(["modprobe", module])
-            except OSError as e:
-                log.error("Could not load kernel module %s: %s" % (module, e))
-                self._supported = False
-                return
-
-            if rc:
-                log.error("Could not load kernel module %s" % module)
-                self._supported = False
-                return
-
-        # If we successfully loaded a kernel module, for this filesystem, we
-        # also need to update the list of supported filesystems.
-        kernel_filesystems = get_kernel_filesystems()
-
-    def testMount(self, options=None):
-        """ Try to mount the fs and return True if successful. """
-        ret = False
-
-        if self.status:
-            raise RuntimeError("filesystem is already mounted")
-
-        # create a temp dir
-        prefix = "%s.%s" % (os.path.basename(self.device), self.type)
-        mountpoint = tempfile.mkdtemp(prefix=prefix)
-
-        # try the mount
-        try:
-            self.mount(mountpoint=mountpoint)
-        except Exception as e:
-            log.info("test mount failed: %s" % e)
-        else:
-            self.unmount()
-            ret = True
-        finally:
-            os.rmdir(mountpoint)
-
-        return ret
-
-    def mount(self, *args, **kwargs):
-        """ Mount this filesystem.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                options -- mount options (overrides all other option strings)
-                chroot -- prefix to apply to mountpoint
-                mountpoint -- mountpoint (overrides self.mountpoint)
-        """
-        options = kwargs.get("options", "")
-        chroot = kwargs.get("chroot", "/")
-        mountpoint = kwargs.get("mountpoint")
-
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not mountpoint:
-            mountpoint = self.mountpoint
-
-        if not mountpoint:
-            raise FSError("no mountpoint given")
-
-        if self.status:
-            return
-
-        if not isinstance(self, NoDevFS) and not os.path.exists(self.device):
-            raise FSError("device %s does not exist" % self.device)
-
-        # XXX os.path.join is FUBAR:
-        #
-        #         os.path.join("/mnt/foo", "/") -> "/"
-        #
-        #mountpoint = os.path.join(chroot, mountpoint)
-        chrootedMountpoint = os.path.normpath("%s/%s" % (chroot, mountpoint))
-        util.makedirs(chrootedMountpoint)
-        if flags.selinux:
-            ret = util.reset_file_context(mountpoint, chroot)
-            log.info("set SELinux context for mountpoint %s to %s" \
-                     % (mountpoint, ret))
-
-        # passed in options override default options
-        if not options or not isinstance(options, str):
-            options = self.options
-
-        if isinstance(self, BindFS):
-            options = "bind," + options
-
-        try: 
-            rc = util.mount(self.device, chrootedMountpoint,
-                            fstype=self.mountType,
-                            options=options)
-        except Exception as e:
-            raise FSError("mount failed: %s" % e)
-
-        if rc:
-            raise FSError("mount failed: %s" % rc)
-
-        if flags.selinux and "ro" not in options.split(","):
-            ret = util.reset_file_context(mountpoint, chroot)
-            log.info("set SELinux context for newly mounted filesystem "
-                     "root at %s to %s" %(mountpoint, ret))
-            util.set_file_context("%s/lost+found" % mountpoint,
-                               lost_and_found_context, chroot)
-
-        self._mountpoint = chrootedMountpoint
-
-    def unmount(self):
-        """ Unmount this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self._mountpoint:
-            # not mounted
-            return
-
-        if not os.path.exists(self._mountpoint):
-            raise FSError("mountpoint does not exist")
-
-        rc = util.umount(self._mountpoint)
-        if rc:
-            raise FSError("umount failed")
-
-        self._mountpoint = None
-
-    def _getLabelArgs(self, label):
-        argv = []
-        argv.extend(self.defaultLabelOptions)
-        argv.extend([self.device, label])
-        return argv 
-
-    def writeLabel(self, label):
-        """ Create a label for this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.labelfsProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        argv = self._getLabelArgs(label)
-        rc = util.run_program([self.labelfsProg] + argv)
-        if rc:
-            raise FSError("label failed")
-
-        self.label = label
-        self.notifyKernel()
-
-    def _getRandomUUID(self):
-        uuid = util.capture_output(["uuidgen"]).strip()
-        return uuid
-
-    def writeRandomUUID(self):
-        raise NotImplementedError("FS does not implement writeRandomUUID")
-
-    @property
-    def needsFSCheck(self):
-        return False
-
-    @property
-    def mkfsProg(self):
-        """ Program used to create filesystems of this type. """
-        return self._mkfs
-
-    @property
-    def fsckProg(self):
-        """ Program used to check filesystems of this type. """
-        return self._fsck
-
-    @property
-    def resizefsProg(self):
-        """ Program used to resize filesystems of this type. """
-        return self._resizefs
-
-    @property
-    def labelfsProg(self):
-        """ Program used to manage labels for this filesystem type. """
-        return self._labelfs
-
-    @property
-    def infofsProg(self):
-        """ Program used to get information for this filesystem type. """
-        return self._infofs
-
-    @property
-    def utilsAvailable(self):
-        # we aren't checking for fsck because we shouldn't need it
-        for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg,
-                     self.infofsProg]:
-            if not prog:
-                continue
-
-            if not util.find_program_in_path(prog):
-                return False
-
-        return True
-
-    @property
-    def supported(self):
-        log_method_call(self, supported=self._supported)
-        return self._supported and self.utilsAvailable
-
-    @property
-    def mountable(self):
-        canmount = (self.mountType in kernel_filesystems) or \
-                   (os.access("/sbin/mount.%s" % (self.mountType,), os.X_OK))
-        modpath = os.path.realpath(os.path.join("/lib/modules", os.uname()[2]))
-        modname = "%s.ko" % self.mountType
-
-        if not canmount and os.path.isdir(modpath):
-            for root, dirs, files in os.walk(modpath):
-                have = filter(lambda x: x.startswith(modname), files)
-                if len(have) == 1 and have[0].startswith(modname):
-                    return True
-
-        return canmount
-
-    @property
-    def resizable(self):
-        """ Can formats of this filesystem type be resized? """
-        return super(FS, self).resizable and self.utilsAvailable
-
-    @property
-    def defaultFormatOptions(self):
-        """ Default options passed to mkfs for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultFormatOptions[:]
-
-    @property
-    def defaultMountOptions(self):
-        """ Default options passed to mount for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultMountOptions[:]
-
-    @property
-    def defaultLabelOptions(self):
-        """ Default options passed to labeler for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultLabelOptions[:]
-
-    @property
-    def defaultCheckOptions(self):
-        """ Default options passed to checker for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultCheckOptions[:]
-
-    def _getOptions(self):
-        options = ",".join(self.defaultMountOptions)
-        if self.mountopts:
-            # XXX should we clobber or append?
-            options = self.mountopts
-        return options
-
-    def _setOptions(self, options):
-        self.mountopts = options
-
-    options = property(_getOptions, _setOptions)
-
-    @property
-    def mountType(self):
-        if not self._mountType:
-            self._mountType = self._type
-
-        return self._mountType
-
-    # These methods just wrap filesystem-specific methods in more
-    # generically named methods so filesystems and formatted devices
-    # like swap and LVM physical volumes can have a common API.
-    def create(self, *args, **kwargs):
-        if self.exists:
-            raise FSError("filesystem already exists")
-
-        DeviceFormat.create(self, *args, **kwargs)
-
-        return self.doFormat(*args, **kwargs)
-
-    def setup(self, *args, **kwargs):
-        """ Mount the filesystem.
-
-            The filesystem will be mounted at the directory indicated by
-            self.mountpoint.
-        """
-        return self.mount(**kwargs)
-
-    def teardown(self, *args, **kwargs):
-        return self.unmount(*args, **kwargs)
-
-    @property
-    def status(self):
-        # FIXME check /proc/mounts or similar
-        if not self.exists:
-            return False
-        return self._mountpoint is not None
-
-    def sync(self, root="/"):
-        pass
-
-class Ext2FS(FS):
-    """ ext2 filesystem. """
-    _type = "ext2"
-    _mkfs = "mke2fs"
-    _modules = ["ext2"]
-    _resizefs = "resize2fs"
-    _labelfs = "e2label"
-    _fsck = "e2fsck"
-    _fsckErrors = {4: _("File system errors left uncorrected."),
-                   8: _("Operational error."),
-                   16: _("Usage or syntax error."),
-                   32: _("e2fsck cancelled by user request."),
-                   128: _("Shared library error.")}
-    _packages = ["e2fsprogs"]
-    _formattable = True
-    _supported = True
-    _resizable = True
-    _linuxNative = True
-    _maxSize = 8 * 1024 * 1024
-    _minSize = 0
-    _defaultFormatOptions = []
-    _defaultMountOptions = ["defaults"]
-    _defaultCheckOptions = ["-f", "-p", "-C", "0"]
-    _dump = True
-    _check = True
-    _infofs = "dumpe2fs"
-    _defaultInfoOptions = ["-h"]
-    _existingSizeFields = ["Block count:", "Block size:"]
-    _fsProfileSpecifier = "-T"
-    partedSystem = fileSystemType["ext2"]
-
-    def __init__(self, *args, **kwargs):
-        self.dirty = False
-        self.errors = False
-        super(Ext2FS, self).__init__(*args, **kwargs)
-
-    def _fsckFailed(self, rc):
-        for errorCode in self._fsckErrors.keys():
-            if rc & errorCode:
-                return True
-        return False
-
-    def _fsckErrorMessage(self, rc):
-        msg = ''
-
-        for errorCode in self._fsckErrors.keys():
-            if rc & errorCode:
-                msg += "\n" + self._fsckErrors[errorCode]
-
-        return msg.strip()
-
-    def writeRandomUUID(self):
-        if not self.exists:
-            raise FSError("filesystem does not exist")
-
-        err = None
-        try:
-            rc = util.run_program(["tune2fs", "-U", "random", self.device])
-        except OSError as e:
-            err = str(e)
-        else:
-            if rc:
-                err = rc
-
-        if err:
-            raise FSError("failed to set UUID for %s: %s" % (self.device, err))
-
-    @property
-    def minSize(self):
-        """ Minimum size for this filesystem in MB. """
-        if self._minInstanceSize is None:
-            # try once in the beginning to get the minimum size for an
-            # existing filesystem.
-            size = self._minSize
-            blockSize = None
-
-            if self.exists and os.path.exists(self.device):
-                # get block size
-                buf = util.capture_output([self.infofsProg, "-h", self.device])
-                for line in buf.splitlines():
-                    if line.startswith("Block size:"):
-                        blockSize = int(line.split(" ")[-1])
-
-                    if line.startswith("Filesystem state:"):
-                        self.dirty = "not clean" in line
-                        self.errors = "with errors" in line
-
-                if blockSize is None:
-                    raise FSError("failed to get block size for %s filesystem "
-                                  "on %s" % (self.mountType, self.device))
-
-                # get minimum size according to resize2fs
-                buf = util.capture_output([self.resizefsProg,
-                                           "-P", self.device])
-                for line in buf.splitlines():
-                    if "minimum size of the filesystem:" not in line:
-                        continue
-
-                    # line will look like:
-                    # Estimated minimum size of the filesystem: 1148649
-                    #
-                    # NOTE: The minimum size reported is in blocks.  Convert
-                    # to bytes, then megabytes, and finally round up.
-                    (text, sep, minSize) = line.partition(": ")
-                    size = long(minSize) * blockSize
-                    size = math.ceil(size / 1024.0 / 1024.0)
-                    break
-
-                if size is None:
-                    log.warning("failed to get minimum size for %s filesystem "
-                                "on %s" % (self.mountType, self.device))
-                else:
-                    orig_size = size
-                    size = min(size * 1.1, size + 500, self.currentSize)
-                    if orig_size < size:
-                        log.debug("padding min size from %d up to %d" % (orig_size, size))
-                    else:
-                        log.debug("using current size %d as min size" % size)
-
-            self._minInstanceSize = size
-
-        return self._minInstanceSize
-
-    @property
-    def needsFSCheck(self):
-        return self.dirty or self.errors
-
-    @property
-    def resizeArgs(self):
-        argv = ["-p", self.device, "%dM" % (self.targetSize,)]
-        return argv
-
-register_device_format(Ext2FS)
-
-
-class Ext3FS(Ext2FS):
-    """ ext3 filesystem. """
-    _type = "ext3"
-    _defaultFormatOptions = ["-t", "ext3"]
-    _modules = ["ext3"]
-    partedSystem = fileSystemType["ext3"]
-
-    # It is possible for a user to specify an fsprofile that defines a blocksize
-    # smaller than the default of 4096 bytes and therefore to make liars of us
-    # with regard to this maximum filesystem size, but if they're doing such
-    # things they should know the implications of their chosen block size.
-    _maxSize = 16 * 1024 * 1024
-
-    @property
-    def needsFSCheck(self):
-        return self.errors
-
-register_device_format(Ext3FS)
-
-
-class Ext4FS(Ext3FS):
-    """ ext4 filesystem. """
-    _type = "ext4"
-    _defaultFormatOptions = ["-t", "ext4"]
-    _modules = ["ext4"]
-    partedSystem = fileSystemType["ext4"]
-
-register_device_format(Ext4FS)
-
-
-class FATFS(FS):
-    """ FAT filesystem. """
-    _type = "vfat"
-    _mkfs = "mkdosfs"
-    _modules = ["vfat"]
-    _labelfs = "dosfslabel"
-    _fsck = "dosfsck"
-    _fsckErrors = {1: _("Recoverable errors have been detected or dosfsck has "
-                        "discovered an internal inconsistency."),
-                   2: _("Usage error.")}
-    _supported = True
-    _formattable = True
-    _maxSize = 1024 * 1024
-    _packages = [ "dosfstools" ]
-    _defaultMountOptions = ["umask=0077", "shortname=winnt"]
-    # FIXME this should be fat32 in some cases
-    partedSystem = fileSystemType["fat16"]
-
-    def _fsckFailed(self, rc):
-        if rc >= 1:
-            return True
-        return False
-
-    def _fsckErrorMessage(self, rc):
-        return self._fsckErrors[rc]
-
-register_device_format(FATFS)
-
-
-class EFIFS(FATFS):
-    _type = "efi"
-    _mountType = "vfat"
-    _modules = ["vfat"]
-    _name = "EFI System Partition"
-    _minSize = 50
-
-    @property
-    def supported(self):
-        return (isinstance(platform.platform, platform.EFI) and
-                self.utilsAvailable)
-
-register_device_format(EFIFS)
-
-
-class BTRFS(FS):
-    """ btrfs filesystem """
-    _type = "btrfs"
-    _mkfs = "mkfs.btrfs"
-    _modules = ["btrfs"]
-    _resizefs = "btrfsctl"
-    _formattable = True
-    _linuxNative = True
-    _maxLabelChars = 256
-    _supported = True
-    _dump = True
-    _check = True
-    _packages = ["btrfs-progs"]
-    _minSize = 256
-    _maxSize = 16 * 1024 * 1024
-    # FIXME parted needs to be taught about btrfs so that we can set the
-    # partition table type correctly for btrfs partitions
-    # partedSystem = fileSystemType["btrfs"]
-
-    def __init__(self, *args, **kwargs):
-        super(BTRFS, self).__init__(*args, **kwargs)
-        self.volUUID = kwargs.pop("volUUID", None)
-
-    def create(self, *args, **kwargs):
-        # filesystem creation is done in storage.devicelibs.btrfs.create_volume
-        pass
-
-    def destroy(self, *args, **kwargs):
-        # filesystem creation is done in storage.devicelibs.btrfs.delete_volume
-        pass
-
-    def setup(self, *args, **kwargs):
-        log_method_call(self, type=self.mountType, device=self.device,
-                        mountpoint=self.mountpoint)
-        if not self.mountpoint and "mountpoint" not in kwargs:
-            # Since btrfs vols have subvols the format setup is automatic.
-            # Don't try to mount it if there's no mountpoint.
-            return
-
-        return self.mount(*args, **kwargs)
-
-    def _getFormatOptions(self, options=None):
-        argv = []
-        if options and isinstance(options, list):
-            argv.extend(options)
-        argv.extend(self.defaultFormatOptions)
-        if self.label:
-            argv.extend(["-L", self.label])
-        argv.append(self.device)
-        return argv
-
-    @property
-    def resizeArgs(self):
-        argv = ["-r", "%dm" % (self.targetSize,), self.device]
-        return argv
-
-register_device_format(BTRFS)
-
-
-class GFS2(FS):
-    """ gfs2 filesystem. """
-    _type = "gfs2"
-    _mkfs = "mkfs.gfs2"
-    _modules = ["dlm", "gfs2"]
-    _formattable = True
-    _defaultFormatOptions = ["-j", "1", "-p", "lock_nolock", "-O"]
-    _linuxNative = True
-    _supported = False
-    _dump = True
-    _check = True
-    _packages = ["gfs2-utils"]
-    # FIXME parted needs to be thaught about btrfs so that we can set the
-    # partition table type correctly for btrfs partitions
-    # partedSystem = fileSystemType["gfs2"]
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.gfs2:
-            supported = self.utilsAvailable
-
-        return supported
-
-register_device_format(GFS2)
-
-
-class JFS(FS):
-    """ JFS filesystem """
-    _type = "jfs"
-    _mkfs = "mkfs.jfs"
-    _modules = ["jfs"]
-    _labelfs = "jfs_tune"
-    _defaultFormatOptions = ["-q"]
-    _defaultLabelOptions = ["-L"]
-    _maxLabelChars = 16
-    _maxSize = 8 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = False
-    _dump = True
-    _check = True
-    _infofs = "jfs_tune"
-    _defaultInfoOptions = ["-l"]
-    _existingSizeFields = ["Aggregate block size:", "Aggregate size:"]
-    partedSystem = fileSystemType["jfs"]
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.jfs:
-            supported = self.utilsAvailable
-
-        return supported
-
-register_device_format(JFS)
-
-
-class ReiserFS(FS):
-    """ reiserfs filesystem """
-    _type = "reiserfs"
-    _mkfs = "mkreiserfs"
-    _resizefs = "resize_reiserfs"
-    _labelfs = "reiserfstune"
-    _modules = ["reiserfs"]
-    _defaultFormatOptions = ["-f", "-f"]
-    _defaultLabelOptions = ["-l"]
-    _maxLabelChars = 16
-    _maxSize = 16 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = False
-    _dump = True
-    _check = True
-    _packages = ["reiserfs-utils"]
-    _infofs = "debugreiserfs"
-    _defaultInfoOptions = []
-    _existingSizeFields = ["Count of blocks on the device:", "Blocksize:"]
-    partedSystem = fileSystemType["reiserfs"]
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.reiserfs:
-            supported = self.utilsAvailable
-
-        return supported
-
-    @property
-    def resizeArgs(self):
-        argv = ["-s", "%dM" % (self.targetSize,), self.device]
-        return argv
-
-register_device_format(ReiserFS)
-
-
-class XFS(FS):
-    """ XFS filesystem """
-    _type = "xfs"
-    _mkfs = "mkfs.xfs"
-    _modules = ["xfs"]
-    _labelfs = "xfs_admin"
-    _defaultFormatOptions = ["-f"]
-    _defaultLabelOptions = ["-L"]
-    _maxLabelChars = 16
-    _maxSize = 16 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = True
-    _dump = True
-    _check = True
-    _packages = ["xfsprogs"]
-    _infofs = "xfs_db"
-    _defaultInfoOptions = ["-c", "\"sb 0\"", "-c", "\"p dblocks\"",
-                           "-c", "\"p blocksize\""]
-    _existingSizeFields = ["dblocks =", "blocksize ="]
-    partedSystem = fileSystemType["xfs"]
-
-    def _getLabelArgs(self, label):
-        argv = []
-        argv.extend(self.defaultLabelOptions)
-        argv.extend([label, self.device])
-        return argv
-
-    def sync(self, root='/'):
-        """ Ensure that data we've written is at least in the journal.
-
-            This is a little odd because xfs_freeze will only be
-            available under the install root.
-        """
-        if not self.status or not self._mountpoint.startswith(root):
-            return
-
-        try:
-            util.run_program(["xfs_freeze", "-f", self.mountpoint], root=root)
-        except OSError as e:
-            log.error("failed to run xfs_freeze: %s" % e)
-
-        try:
-            util.run_program(["xfs_freeze", "-u", self.mountpoint], root=root)
-        except OSError as e:
-            log.error("failed to run xfs_freeze: %s" % e)
-
-register_device_format(XFS)
-
-
-class HFS(FS):
-    _type = "hfs"
-    _mkfs = "hformat"
-    _modules = ["hfs"]
-    _formattable = True
-    partedSystem = fileSystemType["hfs"]
-
-register_device_format(HFS)
-
-
-class AppleBootstrapFS(HFS):
-    _type = "appleboot"
-    _mountType = "hfs"
-    _name = "Apple Bootstrap"
-    _minSize = 800.00 / 1024.00
-    _maxSize = 1
-
-    @property
-    def supported(self):
-        return (isinstance(platform.platform, platform.NewWorldPPC)
-                and self.utilsAvailable)
-
-register_device_format(AppleBootstrapFS)
-
-
-class HFSPlus(FS):
-    _type = "hfs+"
-    _modules = ["hfsplus"]
-    _udevTypes = ["hfsplus"]
-    _mkfs = "mkfs.hfsplus"
-    _fsck = "fsck.hfsplus"
-    _packages = ["hfsplus-tools"]
-    _formattable = True
-    _mountType = "hfsplus"
-    _minSize = 1
-    _maxSize = 2 * 1024 * 1024
-    _check = True
-    partedSystem = fileSystemType["hfs+"]
-
-register_device_format(HFSPlus)
-
-
-class NTFS(FS):
-    """ ntfs filesystem. """
-    _type = "ntfs"
-    _resizefs = "ntfsresize"
-    _fsck = "ntfsresize"
-    _resizable = True
-    _minSize = 1
-    _maxSize = 16 * 1024 * 1024
-    _defaultMountOptions = ["defaults", "ro"]
-    _defaultCheckOptions = ["-c"]
-    _packages = ["ntfsprogs"]
-    _infofs = "ntfsinfo"
-    _defaultInfoOptions = ["-m"]
-    _existingSizeFields = ["Cluster Size:", "Volume Size in Clusters:"]
-    partedSystem = fileSystemType["ntfs"]
-
-    @property
-    def mountable(self):
-        return False
-
-    def _fsckFailed(self, rc):
-        if rc != 0:
-            return True
-        return False
-
-    @property
-    def minSize(self):
-        """ The minimum filesystem size in megabytes. """
-        if self._minInstanceSize is None:
-            # we try one time to determine the minimum size.
-            size = self._minSize
-            if self.exists and os.path.exists(self.device) and \
-               util.find_program_in_path(self.resizefsProg):
-                minSize = None
-                buf = util.run_program([self.resizefsProg, "-m", self.device])
-                for l in buf.split("\n"):
-                    if not l.startswith("Minsize"):
-                        continue
-                    try:
-                        minSize = int(l.split(":")[1].strip())  # MB
-                        minSize *= (mb / mib)                   # MiB
-                    except (IndexError, ValueError) as e:
-                        minSize = None
-                        log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e))
-
-                if minSize is None:
-                    log.warning("Unable to discover minimum size of filesystem "
-                                "on %s" %(self.device,))
-                else:
-                    size = min(minSize * 1.1, minSize + 500, self.currentSize)
-                    if minSize < size:
-                        log.debug("padding min size from %d up to %d" % (minSize, size))
-                    else:
-                        log.debug("using current size %d as min size" % size)
-
-            self._minInstanceSize = size
-
-        return self._minInstanceSize
-
-    @property
-    def resizeArgs(self):
-        # You must supply at least two '-f' options to ntfsresize or
-        # the proceed question will be presented to you.
-
-        # FIXME: This -1 is because our partition alignment calculations plus
-        # converting back and forth between MiB and MB means the filesystem is
-        # getting resized to be slightly larger than the partition holding it.
-        # This hack just makes the filesystem fit.
-        targetSize = (mib / mb) * (self.targetSize-1) # convert MiB to MB
-        argv = ["-ff", "-s", "%dM" % (targetSize,), self.device]
-        return argv
-
-
-register_device_format(NTFS)
-
-
-# if this isn't going to be mountable it might as well not be here
-class NFS(FS):
-    """ NFS filesystem. """
-    _type = "nfs"
-    _modules = ["nfs"]
-
-    def _deviceCheck(self, devspec):
-        if devspec is not None and ":" not in devspec:
-            raise ValueError("device must be of the form <host>:<path>")
-
-    @property
-    def mountable(self):
-        return False
-
-    def _setDevice(self, devspec):
-        self._deviceCheck(devspec)
-        self._device = devspec
-
-    def _getDevice(self):
-        return self._device
-
-    device = property(lambda f: f._getDevice(),
-                      lambda f,d: f._setDevice(d),
-                      doc="Full path the device this format occupies")
- 
-register_device_format(NFS)
-
-
-class NFSv4(NFS):
-    """ NFSv4 filesystem. """
-    _type = "nfs4"
-    _modules = ["nfs4"]
-
-register_device_format(NFSv4)
-
-
-class Iso9660FS(FS):
-    """ ISO9660 filesystem. """
-    _type = "iso9660"
-    _formattable = False
-    _supported = True
-    _resizable = False
-    _linuxNative = False
-    _dump = False
-    _check = False
-    _defaultMountOptions = ["ro"]
-
-register_device_format(Iso9660FS)
-
-
-class NoDevFS(FS):
-    """ nodev filesystem base class """
-    _type = "nodev"
-
-    def __init__(self, *args, **kwargs):
-        FS.__init__(self, *args, **kwargs)
-        self.exists = True
-        self.device = self.type
-
-    def _setDevice(self, devspec):
-        self._device = devspec
-
-    def _getExistingSize(self):
-        pass
-
-register_device_format(NoDevFS)
-
-
-class DevPtsFS(NoDevFS):
-    """ devpts filesystem. """
-    _type = "devpts"
-    _defaultMountOptions = ["gid=5", "mode=620"]
-
-register_device_format(DevPtsFS)
-
-
-# these don't really need to be here
-class ProcFS(NoDevFS):
-    _type = "proc"
-
-register_device_format(ProcFS)
-
-
-class SysFS(NoDevFS):
-    _type = "sysfs"
-
-register_device_format(SysFS)
-
-
-class TmpFS(NoDevFS):
-    _type = "tmpfs"
-
-register_device_format(TmpFS)
-
-
-class BindFS(FS):
-    _type = "bind"
-
-    @property
-    def mountable(self):
-        return True
-
-    def _getExistingSize(self):
-        pass
-
-register_device_format(BindFS)
-
-
-class SELinuxFS(NoDevFS):
-    _type = "selinuxfs"
-
-    @property
-    def mountable(self):
-        return flags.selinux and super(SELinuxFS, self).mountable
-
-register_device_format(SELinuxFS)
-
-
-class USBFS(NoDevFS):
-    _type = "usbfs"
-
-register_device_format(USBFS)
-
diff --git a/pyanaconda/storage/formats/luks.py b/pyanaconda/storage/formats/luks.py
deleted file mode 100644
index 4b37cb4..0000000
--- a/pyanaconda/storage/formats/luks.py
+++ /dev/null
@@ -1,342 +0,0 @@
-# luks.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-
-
-import os
-
-try:
-    import volume_key
-except ImportError:
-    volume_key = None
-
-from ..storage_log import log_method_call
-from ..errors import *
-from ..devicelibs import crypto
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class LUKS(DeviceFormat):
-    """ A LUKS device. """
-    _type = "luks"
-    _name = "LUKS"
-    _lockedName = _("Encrypted")
-    _udevTypes = ["crypto_LUKS"]
-    _formattable = True                 # can be formatted
-    _supported = False                  # is supported
-    _linuxNative = True                 # for clearpart
-    _packages = ["cryptsetup-luks"]     # required packages
-
-    def __init__(self, *args, **kwargs):
-        """ Create a LUKS instance.
-
-            Keyword Arguments:
-
-                device -- the path to the underlying device
-                name -- the name of the mapped device
-                uuid -- this device's UUID
-                passphrase -- device passphrase (string)
-                key_file -- path to a file containing a key (string)
-                cipher -- cipher mode string
-                key_size -- key size in bits
-                exists -- indicates whether this is an existing format
-                escrow_cert -- certificate to use for key escrow
-                add_backup_passphrase -- generate a backup passphrase?
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.cipher = kwargs.get("cipher")
-        self.key_size = kwargs.get("key_size")
-        self.mapName = kwargs.get("name")
-
-        if not self.exists and not self.cipher:
-            self.cipher = "aes-xts-plain64"
-            if not self.key_size:
-                # default to the max (512 bits) for aes-xts
-                self.key_size = 512
-
-        # FIXME: these should both be lists, but managing them will be a pain
-        self.__passphrase = kwargs.get("passphrase")
-        self._key_file = kwargs.get("key_file")
-        self.escrow_cert = kwargs.get("escrow_cert")
-        self.add_backup_passphrase = kwargs.get("add_backup_passphrase", False)
-
-        if not self.mapName and self.exists and self.uuid:
-            self.mapName = "luks-%s" % self.uuid
-        elif not self.mapName and self.device:
-            self.mapName = "luks-%s" % os.path.basename(self.device)
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        if self.__passphrase:
-            passphrase = "(set)"
-        else:
-            passphrase = "(not set)"
-        s += ("  cipher = %(cipher)s  keySize = %(keySize)s"
-              "  mapName = %(mapName)s\n"
-              "  keyFile = %(keyFile)s  passphrase = %(passphrase)s\n"
-              "  escrowCert = %(escrowCert)s  addBackup = %(backup)s" %
-              {"cipher": self.cipher, "keySize": self.key_size,
-               "mapName": self.mapName, "keyFile": self._key_file,
-               "passphrase": passphrase, "escrowCert": self.escrow_cert,
-               "backup": self.add_backup_passphrase})
-        return s
-
-    @property
-    def dict(self):
-        d = super(LUKS, self).dict
-        d.update({"cipher": self.cipher, "keySize": self.key_size,
-                  "mapName": self.mapName, "hasKey": self.hasKey,
-                  "escrowCert": self.escrow_cert,
-                  "backup": self.add_backup_passphrase})
-        return d
-
-    @property
-    def name(self):
-        name = self._name
-        # for existing locked devices, show "Encrypted" instead of LUKS
-        if self.hasKey or not self.exists:
-            name = self._name
-        else:
-            name = "%s (%s)" % (self._lockedName, self._name)
-        return name
-
-    def _setPassphrase(self, passphrase):
-        """ Set the passphrase used to access this device. """
-        self.__passphrase = passphrase
-
-    passphrase = property(fset=_setPassphrase)
-
-    @property
-    def hasKey(self):
-        return ((self.__passphrase not in ["", None]) or
-                (self._key_file and os.access(self._key_file, os.R_OK)))
-
-    @property
-    def configured(self):
-        """ To be ready we need a key or passphrase and a map name. """
-        return self.hasKey and self.mapName
-
-    @property
-    def status(self):
-        if not self.exists or not self.mapName:
-            return False
-        return os.path.exists("/dev/mapper/%s" % self.mapName)
-
-    def probe(self):
-        """ Probe for any missing information about this format.
-
-            cipher mode, key size
-        """
-        raise NotImplementedError("probe method not defined for LUKS")
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, the format. """
-        log_method_call(self, device=self.device, mapName=self.mapName,
-                        type=self.type, status=self.status)
-        if not self.configured:
-            raise LUKSError("luks device not configured")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-        crypto.luks_open(self.device, self.mapName,
-                       passphrase=self.__passphrase,
-                       key_file=self._key_file)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        if self.status:
-            log.debug("unmapping %s" % self.mapName)
-            crypto.luks_close(self.mapName)
-
-    def create(self, *args, **kwargs):
-        """ Create the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.hasKey:
-            raise LUKSError("luks device has no key/passphrase")
-
-        try:
-            DeviceFormat.create(self, *args, **kwargs)
-            crypto.luks_format(self.device,
-                             passphrase=self.__passphrase,
-                             key_file=self._key_file,
-                             cipher=self.cipher,
-                             key_size=self.key_size)
-        except Exception:
-            raise
-        else:
-            self.uuid = crypto.luks_uuid(self.device)
-            self.exists = True
-            self.mapName = "luks-%s" % self.uuid
-            self.notifyKernel()
-
-    def destroy(self, *args, **kwargs):
-        """ Create the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        self.teardown()
-        DeviceFormat.destroy(self, *args, **kwargs)
-
-    @property
-    def keyFile(self):
-        """ Path to key file to be used in /etc/crypttab """
-        return self._key_file
-
-    def addKeyFromFile(self, keyfile):
-        """ Add a new key from a file.
-
-            Add the contents of the specified key file to an available key
-            slot in the LUKS header.
-        """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status, file=keyfile)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_add_key(self.device,
-                          passphrase=self.__passphrase,
-                          key_file=self._key_file,
-                          new_key_file=keyfile)
-
-    def addPassphrase(self, passphrase):
-        """ Add a new passphrase.
-
-            Add the specified passphrase to an available key slot in the
-            LUKS header.
-        """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_add_key(self.device,
-                          passphrase=self.__passphrase,
-                          key_file=self._key_file,
-                          new_passphrase=passphrase)
-
-    def removeKeyFromFile(self, keyfile):
-        """ Remove a key contained in a file.
-
-            Remove key contained in the specified key file from the LUKS
-            header.
-        """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status, file=keyfile)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_remove_key(self.device,
-                             passphrase=self.__passphrase,
-                             key_file=self._key_file,
-                             del_key_file=keyfile)
-
-
-    def removePassphrase(self, passphrase):
-        """ Remove the specified passphrase from the LUKS header. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_remove_key(self.device,
-                             passphrase=self.__passphrase,
-                             key_file=self._key_file,
-                             del_passphrase=passphrase)
-
-    def _escrowVolumeIdent(self, vol):
-        """ Return an escrow packet filename prefix for a volume_key.Volume. """
-        label = vol.label
-        if label is not None:
-            label = label.replace("/", "_")
-        uuid = vol.uuid
-        if uuid is not None:
-            uuid = uuid.replace("/", "_")
-        # uuid is never None on LUKS volumes
-        if label is not None and uuid is not None:
-            volume_ident = "%s-%s" % (label, uuid)
-        elif uuid is not None:
-            volume_ident = uuid
-        elif label is not None:
-            volume_ident = label
-        else:
-            volume_ident = "_unknown"
-        return volume_ident
-
-    def escrow(self, directory, backupPassphrase):
-        log.debug("escrow: escrowVolume start for %s" % self.device)
-        if volume_key is None:
-            raise LUKSError("Missing key escrow support libraries")
-
-        vol = volume_key.Volume.open(self.device)
-        volume_ident = self._escrowVolumeIdent(vol)
-
-        ui = volume_key.UI()
-        # This callback is not expected to be used, let it always fail
-        ui.generic_cb = lambda unused_prompt, unused_echo: None
-        def known_passphrase_cb(unused_prompt, failed_attempts):
-            if failed_attempts == 0:
-                return self.__passphrase
-            return None
-        ui.passphrase_cb = known_passphrase_cb
-
-        log.debug("escrow: getting secret")
-        vol.get_secret(volume_key.SECRET_DEFAULT, ui)
-        log.debug("escrow: creating packet")
-        default_packet = vol.create_packet_assymetric_from_cert_data \
-            (volume_key.SECRET_DEFAULT, self.escrow_cert, ui)
-        log.debug("escrow: packet created")
-        with open("%s/%s-escrow" % (directory, volume_ident), "wb") as f:
-            f.write(default_packet)
-        log.debug("escrow: packet written")
-
-        if self.add_backup_passphrase:
-            log.debug("escrow: adding backup passphrase")
-            vol.add_secret(volume_key.SECRET_PASSPHRASE, backupPassphrase)
-            log.debug("escrow: creating backup packet")
-            backup_passphrase_packet = \
-                vol.create_packet_assymetric_from_cert_data \
-                (volume_key.SECRET_PASSPHRASE, self.escrow_cert, ui)
-            log.debug("escrow: backup packet created")
-            with open("%s/%s-escrow-backup-passphrase" %
-                      (directory, volume_ident), "wb") as f:
-                f.write(backup_passphrase_packet)
-            log.debug("escrow: backup packet written")
-
-        log.debug("escrow: escrowVolume done for %s" % repr(self.device))
-
-
-register_device_format(LUKS)
-
diff --git a/pyanaconda/storage/formats/lvmpv.py b/pyanaconda/storage/formats/lvmpv.py
deleted file mode 100644
index d804711..0000000
--- a/pyanaconda/storage/formats/lvmpv.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# lvmpv.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-
-from ..storage_log import log_method_call
-from parted import PARTITION_LVM
-from ..errors import *
-from ..devicelibs import lvm
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class LVMPhysicalVolume(DeviceFormat):
-    """ An LVM physical volume. """
-    _type = "lvmpv"
-    _name = "physical volume (LVM)"
-    _udevTypes = ["LVM2_member"]
-    partedFlag = PARTITION_LVM
-    _formattable = True                 # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = True                 # for clearpart
-    _minSize = lvm.LVM_PE_SIZE * 2      # one for metadata and one for data
-    _packages = ["lvm2"]                # required packages
-
-    def __init__(self, *args, **kwargs):
-        """ Create an LVMPhysicalVolume instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this PV's uuid (not the VG uuid)
-                vgName -- the name of the VG this PV belongs to
-                vgUuid -- the UUID of the VG this PV belongs to
-                peStart -- offset of first physical extent
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.vgName = kwargs.get("vgName")
-        self.vgUuid = kwargs.get("vgUuid")
-        # 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)    # in MB
-
-        self.inconsistentVG = False
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        s += ("  vgName = %(vgName)s  vgUUID = %(vgUUID)s"
-              "  peStart = %(peStart)s" %
-              {"vgName": self.vgName, "vgUUID": self.vgUuid,
-               "peStart": self.peStart})
-        return s
-
-    @property
-    def dict(self):
-        d = super(LVMPhysicalVolume, self).dict
-        d.update({"vgName": self.vgName, "vgUUID": self.vgUuid,
-                  "peStart": self.peStart})
-        return d
-
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise PhysicalVolumeError("format has not been created")
-
-        #info = lvm.pvinfo(self.device)
-        #self.vgName = info['vg_name']
-        #self.vgUuid = info['vg_uuid']
-
-    def create(self, *args, **kwargs):
-        """ Create the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-        try:
-            DeviceFormat.create(self, *args, **kwargs)
-            # Consider use of -Z|--zero
-            # -f|--force or -y|--yes may be required
-
-            # lvm has issues with persistence of metadata, so here comes the
-            # hammer...
-            DeviceFormat.destroy(self, *args, **kwargs)
-
-            lvm.pvcreate(self.device)
-        except Exception:
-            raise
-        else:
-            self.exists = True
-            self.notifyKernel()
-
-    def destroy(self, *args, **kwargs):
-        """ Destroy the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise PhysicalVolumeError("format has not been created")
-
-        if self.status:
-            raise PhysicalVolumeError("device is active")
-
-        # FIXME: verify path exists?
-        try:
-            lvm.pvremove(self.device)
-        except LVMError:
-            DeviceFormat.destroy(self, *args, **kwargs)
-
-        self.exists = False
-        self.notifyKernel()
-
-    @property
-    def status(self):
-        # XXX hack
-        return (self.exists and self.vgName and
-                os.path.isdir("/dev/mapper/%s" % self.vgName))
-
-register_device_format(LVMPhysicalVolume)
-
diff --git a/pyanaconda/storage/formats/mdraid.py b/pyanaconda/storage/formats/mdraid.py
deleted file mode 100644
index 9d1e26e..0000000
--- a/pyanaconda/storage/formats/mdraid.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# mdraid.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import os
-
-from ..storage_log import log_method_call
-from parted import PARTITION_RAID
-from ..errors import *
-from ..devicelibs import mdraid
-from . import DeviceFormat, register_device_format
-from ..flags import flags
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class MDRaidMember(DeviceFormat):
-    """ An mdraid member disk. """
-    _type = "mdmember"
-    _name = "software RAID"
-    _udevTypes = ["linux_raid_member"]
-    partedFlag = PARTITION_RAID
-    _formattable = True                 # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = True                 # for clearpart
-    _packages = ["mdadm"]               # required packages
-    
-    def __init__(self, *args, **kwargs):
-        """ Create a MDRaidMember instance.
-
-            Keyword Arguments:
-
-                device -- path to underlying device
-                uuid -- this member device's uuid
-                mdUuid -- the uuid of the array this device belongs to
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.mdUuid = kwargs.get("mdUuid")
-        self.raidMinor = None
-
-        #self.probe()
-        self.biosraid = kwargs.get("biosraid")
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        s += ("  mdUUID = %(mdUUID)s  biosraid = %(biosraid)s" %
-              {"mdUUID": self.mdUuid, "biosraid": self.biosraid})
-        return s
-
-    @property
-    def dict(self):
-        d = super(MDRaidMember, self).dict
-        d.update({"mdUUID": self.mdUuid, "biosraid": self.biosraid})
-        return d
-
-    def probe(self):
-        """ Probe for any missing information about this format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise MDMemberError("format does not exist")
-
-        info = mdraid.mdexamine(self.device)
-        if self.uuid is None:
-            self.uuid = info['uuid']
-        if self.raidMinor is None:
-            self.raidMinor = info['mdMinor']
-
-    def destroy(self, *args, **kwargs):
-        if not self.exists:
-            raise MDMemberError("format does not exist")
-
-        if not os.access(self.device, os.W_OK):
-            raise MDMemberError("device path does not exist")
-
-        mdraid.mddestroy(self.device)
-        self.exists = False
-
-    @property
-    def status(self):
-        # XXX hack -- we don't have a nice way to see if the array is active
-        return False
-
-    @property
-    def hidden(self):
-        return (self._hidden or self.biosraid)
-
-# nodmraid -> Wether to use BIOS RAID or not
-# Note the anaconda cmdline has not been parsed yet when we're first imported,
-# so we can not use flags.dmraid here
-if not flags.noiswmd and flags.dmraid:
-    MDRaidMember._udevTypes.append("isw_raid_member")
-
-register_device_format(MDRaidMember)
-
diff --git a/pyanaconda/storage/formats/multipath.py b/pyanaconda/storage/formats/multipath.py
deleted file mode 100644
index 01d69ee..0000000
--- a/pyanaconda/storage/formats/multipath.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# multipath.py
-# multipath device formats
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Any Red Hat trademarks that are incorporated in the source code or
-# documentation are not subject to the GNU General Public License and
-# may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Peter Jones <pjones@redhat.com>
-#
-
-from ..storage_log import log_method_call
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-class MultipathMember(DeviceFormat):
-    """ A multipath member disk. """
-    _type = "multipath_member"
-    _name = "multipath member device"
-    _udev_types = ["multipath_member"]
-    _formattable = False                # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = False                # for clearpart
-    _packages = ["device-mapper-multipath"] # required packages
-    _resizable = False                  # can be resized
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _hidden = True                      # hide devices with this formatting?
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-            On initialization this format is like DeviceFormat
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        # Initialize the attribute that will hold the block object.
-        self._member = None
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        s += ("  member = %(member)r" % {"member": self.member})
-        return s
-
-    def _getMember(self):
-        return self._member
-
-    def _setMember(self, member):
-        self._member = member
-
-    member = property(lambda s: s._getMember(),
-                      lambda s,m: s._setMember(m))
-
-    def create(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise MultipathMemberError("creation of multipath members is non-sense")
-
-    def destroy(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise MultipathMemberError("destruction of multipath members is non-sense")
-
-register_device_format(MultipathMember)
-
diff --git a/pyanaconda/storage/formats/prepboot.py b/pyanaconda/storage/formats/prepboot.py
deleted file mode 100644
index dd2cf8c..0000000
--- a/pyanaconda/storage/formats/prepboot.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# prepboot.py
-# Format class for PPC PReP Boot.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-from ..errors import *
-from .. import platform
-from . import DeviceFormat, register_device_format
-from parted import PARTITION_PREP
-import os
-import logging
-log = logging.getLogger("storage")
-
-class PPCPRePBoot(DeviceFormat):
-    """ Generic device format. """
-    _type = "prepboot"
-    _name = "PPC PReP Boot"
-    _udevTypes = []
-    partedFlag = PARTITION_PREP
-    _formattable = True                 # can be formatted
-    _linuxNative = True                 # for clearpart
-    _maxSize = 10                       # maximum size in MB
-    _minSize = 4                        # minimum size in MB
-
-    def __init__(self, *args, **kwargs):
-        """ Create a PRePBoot instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                exists -- indicates whether this is an existing format
-
-        """
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-    def create(self, *args, **kwargs):
-        if self.exists:
-            raise FSError("PReP Boot format already exists")
-
-        DeviceFormat.create(self, *args, **kwargs)
-
-        try:
-            fd = os.open(self.device, os.O_RDWR)
-            length = os.lseek(fd, 0, os.SEEK_END)
-            os.lseek(fd, 0, os.SEEK_SET)
-            buf = '\0' * 1024 * 1024
-            while length > 0:
-                if length >= len(buf):
-                     os.write(fd, buf)
-                     length -= len(buf)
-                else:
-                     buf = '0' * length
-                     os.write(fd, buf)
-                     length = 0
-            os.close(fd)
-        except OSError as e:
-            log.error("error zeroing out %s: %s" % (self.device, e))
-            if fd:
-                os.close(fd)
-
-    @property
-    def status(self):
-        return False
-
-    @property
-    def supported(self):
-        return isinstance(platform.platform, platform.IPSeriesPPC)
-
-register_device_format(PPCPRePBoot)
-
diff --git a/pyanaconda/storage/formats/swap.py b/pyanaconda/storage/formats/swap.py
deleted file mode 100644
index 903fe6e..0000000
--- a/pyanaconda/storage/formats/swap.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# swap.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-from parted import PARTITION_SWAP, fileSystemType
-from ..storage_log import log_method_call
-from ..errors import *
-from ..util import numeric_type
-from ..devicelibs import swap
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class SwapSpace(DeviceFormat):
-    """ Swap space """
-    _type = "swap"
-    _name = None
-    _udevTypes = ["swap"]
-    partedFlag = PARTITION_SWAP
-    partedSystem = fileSystemType["linux-swap(v1)"]
-    _formattable = True                # can be formatted
-    _supported = True                  # is supported
-    _linuxNative = True                # for clearpart
-
-    #see rhbz#744129 for details
-    _maxSize = 128 * 1024
-
-    def __init__(self, *args, **kwargs):
-        """ Create a SwapSpace instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this swap space's uuid
-                label -- this swap space's label
-                priority -- this swap space's priority
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        self.priority = kwargs.get("priority")
-        self.label = kwargs.get("label")
-
-    def __repr__(self):
-        s = DeviceFormat.__repr__(self)
-        s += ("  priority = %(priority)s  label = %(label)s" %
-              {"priority": self.priority, "label": self.label})
-        return s
-
-    @property
-    def dict(self):
-        d = super(SwapSpace, self).dict
-        d.update({"priority": self.priority, "label": self.label})
-        return d
-
-    def _setPriority(self, priority):
-        if priority is None:
-            self._priority = None
-            return
-
-        if not isinstance(priority, int) or not 0 <= priority <= 32767:
-            raise ValueError("swap priority must be an integer between 0 and 32767")
-
-        self._priority = priority
-
-    def _getPriority(self):
-        return self._priority
-
-    priority = property(_getPriority, _setPriority,
-                        doc="The priority of the swap device")
-
-    def _getOptions(self):
-        opts = ""
-        if self.priority is not None:
-            opts += "pri=%d" % self.priority
-
-        return opts
-
-    def _setOptions(self, opts):
-        if not opts:
-            self.priority = None
-            return
-
-        for option in opts.split(","):
-            (opt, equals, arg) = option.partition("=")
-            if equals and opt == "pri":
-                try:
-                    self.priority = int(arg)
-                except ValueError:
-                    log.info("invalid value for swap priority: %s" % arg)
-
-    options = property(_getOptions, _setOptions,
-                       doc="The swap device's fstab options string")
-
-    @property
-    def status(self):
-        """ Device status. """
-        return self.exists and swap.swapstatus(self.device)
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise SwapSpaceError("format has not been created")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-        swap.swapon(self.device, priority=self.priority)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise SwapSpaceError("format has not been created")
-
-        if self.status:
-            swap.swapoff(self.device)
-
-    def create(self, *args, **kwargs):
-        """ Create the device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        force = kwargs.get("force")
-        if not force and self.exists:
-            raise SwapSpaceError("format already exists")
-
-        if force:
-            self.teardown()
-        elif self.status:
-            raise SwapSpaceError("device exists and is active")
-
-        try:
-            DeviceFormat.create(self, *args, **kwargs)
-            swap.mkswap(self.device, label=self.label)
-        except Exception:
-            raise
-        else:
-            self.exists = True
-            self.notifyKernel()
-
-register_device_format(SwapSpace)
-
diff --git a/pyanaconda/storage/iscsi.py b/pyanaconda/storage/iscsi.py
deleted file mode 100644
index 8b7cbf8..0000000
--- a/pyanaconda/storage/iscsi.py
+++ /dev/null
@@ -1,437 +0,0 @@
-#
-# iscsi.py - iscsi class
-#
-# Copyright (C) 2005, 2006  IBM, Inc.  All rights reserved.
-# Copyright (C) 2006  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-from . import ROOT_PATH
-from udev import udev_settle
-from . import util
-from .flags import flags
-import os
-import logging
-import shutil
-import time
-import hashlib
-import random
-import itertools
-log = logging.getLogger("storage")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-has_libiscsi = True
-try:
-    import libiscsi
-except ImportError:
-    has_libiscsi = False
-
-# Note that stage2 copies all files under /sbin to /usr/sbin
-ISCSID=""
-INITIATOR_FILE="/etc/iscsi/initiatorname.iscsi"
-
-ISCSI_MODULES=['cxgb3i', 'bnx2i', 'be2iscsi']
-
-def has_iscsi():
-    global ISCSID
-
-    if not os.access("/sys/module/iscsi_tcp", os.X_OK):
-        return False
-
-    if not ISCSID:
-        location = util.find_program_in_path("iscsid")
-        if not location:
-            return False
-        ISCSID = location
-        log.info("ISCSID is %s" % (ISCSID,))
-
-    return True
-
-def randomIname():
-    """Generate a random initiator name the same way as iscsi-iname"""
-
-    s = "iqn.1994-05.com.domain:01."
-    m = hashlib.md5()
-    u = os.uname()
-    for i in u:
-        m.update(i)
-    dig = m.hexdigest()
-
-    for i in range(0, 6):
-        s += dig[random.randrange(0, 32)]
-    return s
-
-class iscsi(object):
-    """ iSCSI utility class.
-
-        This class will automatically discover and login to iBFT (or
-        other firmware) configured iscsi devices when the startup() method
-        gets called. It can also be used to manually configure iscsi devices
-        through the addTarget() method.
-
-        As this class needs to make sure certain things like starting iscsid
-        and logging in to firmware discovered disks only happens once
-        and as it keeps a global list of all iSCSI devices it is implemented as
-        a Singleton.
-    """
-
-    def __init__(self):
-        # Dictionary of discovered targets containing list of (node,
-        # logged_in) tuples.
-        self.discovered_targets = {}
-        # This list contains nodes discovered through iBFT (or other firmware)
-        self.ibftNodes = []
-        self._initiator = ""
-        self.initiatorSet = False
-        self.started = False
-        self.ifaces = {}
-
-        if flags.ibft:
-            try:
-                initiatorname = libiscsi.get_firmware_initiator_name()
-                self._initiator = initiatorname
-                self.initiatorSet = True
-            except Exception:
-                pass
-
-    # So that users can write iscsi() to get the singleton instance
-    def __call__(self):
-        return self
-
-    def _getInitiator(self):
-        if self._initiator != "":
-            return self._initiator
-
-        return randomIname()
-
-    def _setInitiator(self, val):
-        if self.initiatorSet and val != self._initiator:
-            raise ValueError, _("Unable to change iSCSI initiator name once set")
-        if len(val) == 0:
-            raise ValueError, _("Must provide an iSCSI initiator name")
-        self._initiator = val
-
-    initiator = property(_getInitiator, _setInitiator)
-
-    def active_nodes(self, target=None):
-        """Nodes logged in to"""
-        if target:
-            return [node for (node, logged_in) in
-                    self.discovered_targets.get(target, [])
-                    if logged_in]
-        else:
-            return [node for (node, logged_in) in
-                    itertools.chain(*self.discovered_targets.values())
-                    if logged_in] + self.ibftNodes
-
-    def _getMode(self):
-        if not self.active_nodes():
-            return "none"
-        if self.ifaces:
-            return "bind"
-        else:
-            return "default"
-
-    mode = property(_getMode)
-
-    def _mark_node_active(self, node, active=True):
-        """Mark node as one logged in to
-
-           Returns False if not found
-        """
-        for target_nodes in self.discovered_targets.values():
-            for nodeinfo in target_nodes:
-                if nodeinfo[0] is node:
-                    nodeinfo[1] = active
-                    return True
-        return False
-
-
-    def _startIBFT(self):
-        if not flags.ibft:
-            return
-
-        try:
-            found_nodes = libiscsi.discover_firmware()
-        except Exception:
-            log.info("iscsi: No IBFT info found.");
-            # an exception here means there is no ibft firmware, just return
-            return
-
-        for node in found_nodes:
-            try:
-                node.login()
-                log.info("iscsi IBFT: logged into %s at %s:%s through %s" % (
-                    node.name, node.address, node.port, node.iface))
-                self.ibftNodes.append(node)
-            except IOError as e:
-                log.error("Could not log into ibft iscsi target %s: %s" %
-                          (node.name, str(e)))
-                pass
-
-        self.stabilize()
-
-    def stabilize(self):
-        # Wait for udev to create the devices for the just added disks
-
-        # It is possible when we get here the events for the new devices
-        # are not send yet, so sleep to make sure the events are fired
-        time.sleep(2)
-        udev_settle()
-
-    def create_interfaces(self, ifaces):
-        for iface in ifaces:
-            iscsi_iface_name = "iface%d" % len(self.ifaces)
-            #iscsiadm -m iface -I iface0 --op=new
-            util.run_program(["iscsiadm", "-m", "iface",
-                              "-I", iscsi_iface_name, "--op=new"])
-            #iscsiadm -m iface -I iface0 --op=update -n iface.net_ifacename -v eth0
-            util.run_program(["iscsiadm", "-m", "iface",
-                              "-I", iscsi_iface_name, "--op=update",
-                              "-n", "iface.net_ifacename", "-v", iface])
-
-            self.ifaces[iscsi_iface_name] = iface
-            log.debug("created_interface %s:%s" % (iscsi_iface_name, iface))
-
-    def delete_interfaces(self):
-        if not self.ifaces:
-            return None
-        for iscsi_iface_name in self.ifaces:
-            #iscsiadm -m iface -I iface0 --op=delete
-            util.run_program(["iscsiadm", "-m", "iface",
-                              "-I", iscsi_iface_name, "--op=delete"])
-        self.ifaces = {}
-
-    def startup(self):
-        if self.started:
-            return
-
-        if not has_iscsi():
-            return
-
-        if self._initiator == "":
-            log.info("no initiator set")
-            return
-
-        log.debug("Setting up %s" % (INITIATOR_FILE, ))
-        log.info("iSCSI initiator name %s", self.initiator)
-        if os.path.exists(INITIATOR_FILE):
-            os.unlink(INITIATOR_FILE)
-        if not os.path.isdir("/etc/iscsi"):
-            os.makedirs("/etc/iscsi", 0755)
-        fd = os.open(INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
-        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
-        os.close(fd)
-        self.initiatorSet = True
-
-        for dir in ['ifaces','isns','nodes','send_targets','slp','static']:
-            fulldir = "/var/lib/iscsi/%s" % (dir,)
-            if not os.path.isdir(fulldir):
-                os.makedirs(fulldir, 0755)
-
-        log.info("iSCSI startup")
-        util.run_program(['modprobe', '-a'] + ISCSI_MODULES)
-        # iscsiuio is needed by Broadcom offload cards (bnx2i). Currently
-        # not present in iscsi-initiator-utils for Fedora.
-        try:
-            iscsiuio = util.find_program_in_path('iscsiuio',
-                                                   raise_on_error=True)
-        except RuntimeError:
-            log.info("iscsi: iscsiuio not found.")
-        else:
-            log.debug("iscsi: iscsiuio is at %s" % iscsiuio)
-            util.run_program([iscsiuio])
-        # run the daemon
-        util.run_program([ISCSID])
-        time.sleep(1)
-
-        self._startIBFT()
-        self.started = True
-
-    def discover(self, ipaddr, port="3260", username=None, password=None,
-                  r_username=None, r_password=None, intf=None):
-        """
-        Discover iSCSI nodes on the target available for login.
-
-        If we are logged in a node discovered for specified target
-        do not do the discovery again as it can corrupt credentials
-        stored for the node (setAuth and getAuth are using database
-        in /var/lib/iscsi/nodes which is filled by discovery). Just
-        return nodes obtained and stored in the first discovery
-        instead.
-
-        Returns list of nodes user can log in.
-        """
-        authinfo = None
-
-        if not has_iscsi():
-            raise IOError, _("iSCSI not available")
-        if self._initiator == "":
-            raise ValueError, _("No initiator name set")
-
-        if self.active_nodes((ipaddr, port)):
-            log.debug("iSCSI: skipping discovery of %s:%s due to active nodes" %
-                      (ipaddr, port))
-        else:
-            if username or password or r_username or r_password:
-                # Note may raise a ValueError
-                authinfo = libiscsi.chapAuthInfo(username=username,
-                                                 password=password,
-                                                 reverse_username=r_username,
-                                                 reverse_password=r_password)
-            self.startup()
-
-            # Note may raise an IOError
-            found_nodes = libiscsi.discover_sendtargets(address=ipaddr,
-                                                        port=int(port),
-                                                        authinfo=authinfo)
-            if found_nodes is None:
-                return None
-            self.discovered_targets[(ipaddr, port)] = []
-            for node in found_nodes:
-                self.discovered_targets[(ipaddr, port)].append([node, False])
-                log.debug("discovered iSCSI node: %s" % node.name)
-
-        # only return the nodes we are not logged into yet
-        return [node for (node, logged_in) in
-                self.discovered_targets[(ipaddr, port)]
-                if not logged_in]
-
-    def log_into_node(self, node, username=None, password=None,
-                  r_username=None, r_password=None, intf=None):
-        """
-        Raises IOError.
-        """
-        rc = False # assume failure
-        msg = ""
-
-        if intf:
-            w = intf.waitWindow(_("Logging in to iSCSI node"),
-                                _("Logging in to iSCSI node %s") % node.name)
-        try:
-            authinfo = None
-            if username or password or r_username or r_password:
-                # may raise a ValueError
-                authinfo = libiscsi.chapAuthInfo(username=username,
-                                                 password=password,
-                                                 reverse_username=r_username,
-                                                 reverse_password=r_password)
-            node.setAuth(authinfo)
-            node.login()
-            rc = True
-            log.info("iSCSI: logged into %s at %s:%s through %s" % (
-                    node.name, node.address, node.port, node.iface))
-            if not self._mark_node_active(node):
-                log.error("iSCSI: node not found among discovered")
-        except (IOError, ValueError) as e:
-            msg = str(e)
-            log.warning("iSCSI: could not log into %s: %s" % (node.name, msg))
-        if intf:
-            w.pop()
-
-        return (rc, msg)
-
-    # NOTE: the same credentials are used for discovery and login
-    #       (unlike in UI)
-    def addTarget(self, ipaddr, port="3260", user=None, pw=None,
-                  user_in=None, pw_in=None, intf=None, target=None, iface=None):
-        found = 0
-        logged_in = 0
-
-        found_nodes = self.discover(ipaddr, port, user, pw, user_in, pw_in,
-                                    intf)
-        if found_nodes == None:
-            raise IOError, _("No iSCSI nodes discovered")
-
-        for node in found_nodes:
-            if target and target != node.name:
-                log.debug("iscsi: skipping logging to iscsi node '%s'" %
-                          node.name)
-                continue
-            if iface:
-                node_net_iface = self.ifaces.get(node.iface, node.iface)
-                if iface != node_net_iface:
-                    log.debug("iscsi: skipping logging to iscsi node '%s' via %s" %
-                               (node.name, node_net_iface))
-                    continue
-
-            found = found + 1
-
-            (rc, msg) = self.log_into_node(node, user, pw, user_in, pw_in,
-                                           intf)
-            if rc:
-                logged_in = logged_in +1
-
-        if found == 0:
-            raise IOError, _("No new iSCSI nodes discovered")
-
-        if logged_in == 0:
-            raise IOError, _("Could not log in to any of the discovered nodes")
-
-        self.stabilize(intf)
-
-    def write(self, storage):
-        if not self.initiatorSet:
-            return
-
-        # set iscsi nodes to autostart
-        root = storage.rootDevice
-        for node in self.active_nodes():
-            autostart = True
-            disks = self.getNodeDisks(node, storage)
-            for disk in disks:
-                # nodes used for root get started by the initrd
-                if root.dependsOn(disk):
-                    autostart = False
-
-            if autostart:
-                node.setParameter("node.startup", "automatic")
-
-        if not os.path.isdir(ROOT_PATH + "/etc/iscsi"):
-            os.makedirs(ROOT_PATH + "/etc/iscsi", 0755)
-        fd = os.open(ROOT_PATH + INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
-        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
-        os.close(fd)
-
-        # copy "db" files.  *sigh*
-        if os.path.isdir(ROOT_PATH + "/var/lib/iscsi"):
-            shutil.rmtree(ROOT_PATH + "/var/lib/iscsi")
-        if os.path.isdir("/var/lib/iscsi"):
-            shutil.copytree("/var/lib/iscsi", ROOT_PATH + "/var/lib/iscsi",
-                            symlinks=True)
-
-    def getNode(self, name, address, port, iface):
-        for node in self.active_nodes():
-            if node.name == name and node.address == address and \
-               node.port == int(port) and node.iface == iface:
-                return node
-
-        return None
-
-    def getNodeDisks(self, node, storage):
-        nodeDisks = []
-        iscsiDisks = storage.devicetree.getDevicesByType("iscsi")
-        for disk in iscsiDisks:
-            if disk.node == node:
-                nodeDisks.append(disk)
-
-        return nodeDisks
-
-# Create iscsi singleton
-iscsi = iscsi()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
deleted file mode 100644
index 243c62b..0000000
--- a/pyanaconda/storage/partitioning.py
+++ /dev/null
@@ -1,1947 +0,0 @@
-# partitioning.py
-# Disk partitioning functions.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-import sys
-import os
-from operator import add, sub, gt, lt
-
-import parted
-from pykickstart.constants import *
-
-from errors import *
-from deviceaction import *
-from devices import PartitionDevice, LUKSDevice, devicePathToName
-from formats import getFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def _getCandidateDisks(storage):
-    """ Return a list of disks with space for a default-sized partition. """
-    disks = []
-    for disk in storage.partitioned:
-        if storage.config.clearPartDisks and \
-           (disk.name not in storage.config.clearPartDisks):
-            continue
-
-        part = disk.format.firstPartition
-        while part:
-            if not part.type & parted.PARTITION_FREESPACE:
-                part = part.nextPartition()
-                continue
-
-            if part.getSize(unit="MB") > PartitionDevice.defaultSize:
-                disks.append(disk)
-                break
-
-            part = part.nextPartition()
-
-    return disks
-
-def _scheduleImplicitPartitions(storage, disks):
-    """ Schedule creation of a lvm/btrfs partition on each disk in disks. """
-    # create a separate pv or btrfs partition for each disk with free space
-    devs = []
-
-    # only schedule the partitions if either lvm or btrfs autopart was chosen
-    if storage.autoPartType not in (AUTOPART_TYPE_LVM, AUTOPART_TYPE_BTRFS):
-        return devs
-
-    for disk in disks:
-        if storage.encryptedAutoPart:
-            fmt_type = "luks"
-            fmt_args = {"passphrase": storage.encryptionPassphrase,
-                        "cipher": storage.encryptionCipher,
-                        "escrow_cert": storage.autoPartEscrowCert,
-                        "add_backup_passphrase": storage.autoPartAddBackupPassphrase}
-        else:
-            if storage.autoPartType == AUTOPART_TYPE_LVM:
-                fmt_type = "lvmpv"
-            else:
-                fmt_type = "btrfs"
-            fmt_args = {}
-        part = storage.newPartition(fmt_type=fmt_type,
-                                                fmt_args=fmt_args,
-                                                grow=True,
-                                                parents=[disk])
-        storage.createDevice(part)
-        devs.append(part)
-
-    return devs
-
-def _schedulePartitions(storage, disks):
-    """ Schedule creation of autopart partitions. """
-    # basis for requests with requiredSpace is the sum of the sizes of the
-    # two largest free regions
-    all_free = getFreeRegions(disks)
-    all_free.sort(key=lambda f: f.length, reverse=True)
-    if not all_free:
-        # this should never happen since we've already filtered the disks
-        # to those with at least 500MB free
-        log.error("no free space on disks %s" % ([d.name for d in disks],))
-        return
-
-    free = all_free[0].getSize()
-    if len(all_free) > 1:
-        free += all_free[1].getSize()
-
-    # The boot disk must be set at this point. See if any platform-specific
-    # stage1 device we might allocate already exists on the boot disk.
-    stage1_device = None
-    for device in storage.devices:
-        if storage.bootloader.stage1_disk not in device.disks:
-            continue
-
-        if storage.bootloader.is_valid_stage1_device(device):
-            stage1_device = device
-            break
-
-    #
-    # First pass is for partitions only. We'll do LVs later.
-    #
-    for request in storage.autoPartitionRequests:
-        if (request.lv and storage.autoPartType == AUTOPART_TYPE_LVM) or \
-           (request.btr and storage.autoPartType == AUTOPART_TYPE_BTRFS):
-            continue
-
-        if request.requiredSpace and request.requiredSpace > free:
-            continue
-
-        elif request.fstype in ("prepboot", "efi", "hfs+") and \
-             (storage.bootloader.skip_bootloader or stage1_device):
-            # there should never be a need for more than one of these
-            # partitions, so skip them.
-            log.info("skipping unneeded stage1 %s request" % request.fstype)
-            log.debug(request)
-
-            if request.fstype == "efi":
-                # Set the mountpoint for the existing EFI boot partition
-                stage1_device.format.mountpoint = "/boot/efi"
-
-            log.debug(stage1_device)
-            continue
-        elif request.fstype == "biosboot":
-            is_gpt = (stage1_device and
-                      getattr(stage1_device.format, "labelType", None) == "gpt")
-            has_bios_boot = (stage1_device and
-                             any([p.format.type == "biosboot"
-                                    for p in storage.partitions
-                                        if p.disk == stage1_device]))
-            if (storage.bootloader.skip_bootloader or
-                not (stage1_device and stage1_device.isDisk and
-                    is_gpt and not has_bios_boot)):
-                # there should never be a need for more than one of these
-                # partitions, so skip them.
-                log.info("skipping unneeded stage1 %s request" % request.fstype)
-                log.debug(request)
-                log.debug(stage1_device)
-                continue
-
-        if request.encrypted and storage.encryptedAutoPart:
-            fmt_type = "luks"
-            fmt_args = {"passphrase": storage.encryptionPassphrase,
-                        "cipher": storage.encryptionCipher,
-                        "escrow_cert": storage.autoPartEscrowCert,
-                        "add_backup_passphrase": storage.autoPartAddBackupPassphrase}
-        else:
-            fmt_type = request.fstype
-            fmt_args = {}
-
-        dev = storage.newPartition(fmt_type=fmt_type,
-                                            fmt_args=fmt_args,
-                                            size=request.size,
-                                            grow=request.grow,
-                                            maxsize=request.maxSize,
-                                            mountpoint=request.mountpoint,
-                                            parents=disks,
-                                            weight=request.weight)
-
-        # schedule the device for creation
-        storage.createDevice(dev)
-
-        if request.encrypted and storage.encryptedAutoPart:
-            luks_fmt = getFormat(request.fstype,
-                                 device=dev.path,
-                                 mountpoint=request.mountpoint)
-            luks_dev = LUKSDevice("luks-%s" % dev.name,
-                                  format=luks_fmt,
-                                  size=dev.size,
-                                  parents=dev)
-            storage.createDevice(luks_dev)
-
-    # make sure preexisting broken lvm/raid configs get out of the way
-    return
-
-def _scheduleVolumes(storage, devs):
-    """ Schedule creation of autopart lvm/btrfs volumes. """
-    if not devs:
-        return
-
-    if storage.autoPartType == AUTOPART_TYPE_LVM:
-        new_container = storage.newVG
-        new_volume = storage.newLV
-        format_name = "lvmpv"
-    else:
-        new_container = storage.newBTRFS
-        new_volume = storage.newBTRFS
-        format_name = "btrfs"
-
-    if storage.encryptedAutoPart:
-        pvs = []
-        for dev in devs:
-            pv = LUKSDevice("luks-%s" % dev.name,
-                            format=getFormat(format_name, device=dev.path),
-                            size=dev.size,
-                            parents=dev)
-            pvs.append(pv)
-            storage.createDevice(pv)
-    else:
-        pvs = devs
-
-    # create a vg containing all of the autopart pvs
-    container = new_container(parents=pvs)
-    storage.createDevice(container)
-
-    #
-    # Convert storage.autoPartitionRequests into Device instances and
-    # schedule them for creation.
-    #
-    # Second pass, for LVs only.
-    for request in storage.autoPartitionRequests:
-        btr = storage.autoPartType == AUTOPART_TYPE_BTRFS and request.btr
-        lv = storage.autoPartType == AUTOPART_TYPE_LVM and request.lv
-
-        if not btr and not lv:
-            continue
-
-        # required space isn't relevant on btrfs
-        if lv and \
-           request.requiredSpace and request.requiredSpace > container.size:
-            continue
-
-        if request.fstype is None:
-            if btr:
-                # btrfs volumes can only contain btrfs filesystems
-                request.fstype = "btrfs"
-            else:
-                request.fstype = storage.defaultFSType
-
-        kwargs = {"mountpoint": request.mountpoint,
-                  "fmt_type": request.fstype}
-        if lv:
-            kwargs.update({"parents": [container],
-                           "grow": request.grow,
-                           "maxsize": request.maxSize,
-                           "size": request.size,
-                           "singlePV": request.singlePV})
-        else:
-            kwargs.update({"parents": [container],
-                           "size": request.size,
-                           "subvol": True})
-
-        dev = new_volume(**kwargs)
-
-        # schedule the device for creation
-        storage.createDevice(dev)
-
-def doAutoPartition(storage, data):
-    log.debug("doAutoPart: %s" % storage.doAutoPart)
-    log.debug("encryptedAutoPart: %s" % storage.encryptedAutoPart)
-    log.debug("autoPartType: %s" % storage.autoPartType)
-    log.debug("clearPartType: %s" % storage.config.clearPartType)
-    log.debug("clearPartDisks: %s" % storage.config.clearPartDisks)
-    log.debug("autoPartitionRequests:\n%s" % "".join([str(p) for p in storage.autoPartitionRequests]))
-    log.debug("storage.disks: %s" % [d.name for d in storage.disks])
-    log.debug("storage.partitioned: %s" % [d.name for d in storage.partitioned])
-    log.debug("all names: %s" % [d.name for d in storage.devices])
-    log.debug("boot disk: %s" % getattr(storage.bootDisk, "name", None))
-
-    disks = []
-    devs = []
-
-    if not storage.doAutoPart:
-        return
-
-    if not storage.partitioned:
-        raise NoDisksError(_("No usable disks selected"))
-
-    disks = _getCandidateDisks(storage)
-    devs = _scheduleImplicitPartitions(storage, disks)
-    log.debug("candidate disks: %s" % disks)
-    log.debug("devs: %s" % devs)
-
-    if disks == []:
-        raise NotEnoughFreeSpaceError(_("Not enough free space on disks for "
-                                      "automatic partitioning"))
-
-    _schedulePartitions(storage, disks)
-
-    # run the autopart function to allocate and grow partitions
-    doPartitioning(storage)
-    _scheduleVolumes(storage, devs)
-
-    # grow LVs
-    growLVM(storage)
-
-    storage.setUpBootLoader()
-
-    # now do a full check of the requests
-    (errors, warnings) = storage.sanityCheck()
-    for error in errors:
-        log.error(error)
-    for warning in warnings:
-        log.warning(warning)
-    if errors:
-        raise PartitioningError("\n".join(errors))
-
-def partitionCompare(part1, part2):
-    """ More specifically defined partitions come first.
-
-        < 1 => x < y
-          0 => x == y
-        > 1 => x > y
-    """
-    ret = 0
-
-    if part1.req_base_weight:
-        ret -= part1.req_base_weight
-
-    if part2.req_base_weight:
-        ret += part2.req_base_weight
-
-    # more specific disk specs to the front of the list
-    # req_disks being empty is equivalent to it being an infinitely long list
-    if part1.req_disks and not part2.req_disks:
-        ret -= 500
-    elif not part1.req_disks and part2.req_disks:
-        ret += 500
-    else:
-        ret += cmp(len(part1.req_disks), len(part2.req_disks)) * 500
-
-    # primary-only to the front of the list
-    ret -= cmp(part1.req_primary, part2.req_primary) * 200
-
-    # fixed size requests to the front
-    ret += cmp(part1.req_grow, part2.req_grow) * 100
-
-    # larger requests go to the front of the list
-    ret -= cmp(part1.req_base_size, part2.req_base_size) * 50
-
-    # potentially larger growable requests go to the front
-    if part1.req_grow and part2.req_grow:
-        if not part1.req_max_size and part2.req_max_size:
-            ret -= 25
-        elif part1.req_max_size and not part2.req_max_size:
-            ret += 25
-        else:
-            ret -= cmp(part1.req_max_size, part2.req_max_size) * 25
-
-    # give a little bump based on mountpoint
-    if hasattr(part1.format, "mountpoint") and \
-       hasattr(part2.format, "mountpoint"):
-        ret += cmp(part1.format.mountpoint, part2.format.mountpoint) * 10
-
-    if ret > 0:
-        ret = 1
-    elif ret < 0:
-        ret = -1
-
-    return ret
-
-def getNextPartitionType(disk, no_primary=None):
-    """ Find the type of partition to create next on a disk.
-
-        Return a parted partition type value representing the type of the
-        next partition we will create on this disk.
-
-        If there is only one free primary partition and we can create an
-        extended partition, we do that.
-
-        If there are free primary slots and an extended partition we will
-        recommend creating a primary partition. This can be overridden
-        with the keyword argument no_primary.
-
-        Arguments:
-
-            disk -- a parted.Disk instance representing the disk
-
-        Keyword arguments:
-
-            no_primary -- given a choice between primary and logical
-                          partitions, prefer logical
-
-    """
-    part_type = None
-    extended = disk.getExtendedPartition()
-    supports_extended = disk.supportsFeature(parted.DISK_TYPE_EXTENDED)
-    logical_count = len(disk.getLogicalPartitions())
-    max_logicals = disk.getMaxLogicalPartitions()
-    primary_count = disk.primaryPartitionCount
-
-    if primary_count < disk.maxPrimaryPartitionCount:
-        if primary_count == disk.maxPrimaryPartitionCount - 1:
-            # can we make an extended partition? now's our chance.
-            if not extended and supports_extended:
-                part_type = parted.PARTITION_EXTENDED
-            elif not extended:
-                # extended partitions not supported. primary or nothing.
-                if not no_primary:
-                    part_type = parted.PARTITION_NORMAL
-            else:
-                # there is an extended and a free primary
-                if not no_primary:
-                    part_type = parted.PARTITION_NORMAL
-                elif logical_count < max_logicals:
-                    # we have an extended with logical slots, so use one.
-                    part_type = parted.PARTITION_LOGICAL
-        else:
-            # there are two or more primary slots left. use one unless we're
-            # not supposed to make primaries.
-            if not no_primary:
-                part_type = parted.PARTITION_NORMAL
-            elif extended and logical_count < max_logicals:
-                part_type = parted.PARTITION_LOGICAL
-    elif extended and logical_count < max_logicals:
-        part_type = parted.PARTITION_LOGICAL
-
-    return part_type
-
-def getBestFreeSpaceRegion(disk, part_type, req_size,
-                           boot=None, best_free=None, grow=None):
-    """ Return the "best" free region on the specified disk.
-
-        For non-boot partitions, we return the largest free region on the
-        disk. For boot partitions, we return the first region that is
-        large enough to hold the partition.
-
-        Partition type (parted's PARTITION_NORMAL, PARTITION_LOGICAL) is
-        taken into account when locating a suitable free region.
-
-        For locating the best region from among several disks, the keyword
-        argument best_free allows the specification of a current "best"
-        free region with which to compare the best from this disk. The
-        overall best region is returned.
-
-        Arguments:
-
-            disk -- the disk (a parted.Disk instance)
-            part_type -- the type of partition we want to allocate
-                         (one of parted's partition type constants)
-            req_size -- the requested size of the partition (in MB)
-
-        Keyword arguments:
-
-            boot -- indicates whether this will be a bootable partition
-                    (boolean)
-            best_free -- current best free region for this partition
-            grow -- indicates whether this is a growable request
-
-    """
-    log.debug("getBestFreeSpaceRegion: disk=%s part_type=%d req_size=%dMB "
-              "boot=%s best=%s grow=%s" %
-              (disk.device.path, part_type, req_size, boot, best_free, grow))
-    extended = disk.getExtendedPartition()
-
-    for _range in disk.getFreeSpaceRegions():
-        if extended:
-            # find out if there is any overlap between this region and the
-            # extended partition
-            log.debug("looking for intersection between extended (%d-%d) and free (%d-%d)" %
-                    (extended.geometry.start, extended.geometry.end, _range.start, _range.end))
-
-            # parted.Geometry.overlapsWith can handle this
-            try:
-                free_geom = extended.geometry.intersect(_range)
-            except ArithmeticError:
-                # this freespace region does not lie within the extended
-                # partition's geometry
-                free_geom = None
-
-            if (free_geom and part_type == parted.PARTITION_NORMAL) or \
-               (not free_geom and part_type == parted.PARTITION_LOGICAL):
-                log.debug("free region not suitable for request")
-                continue
-
-            if part_type == parted.PARTITION_NORMAL:
-                # we're allocating a primary and the region is not within
-                # the extended, so we use the original region
-                free_geom = _range
-        else:
-            free_geom = _range
-
-        if free_geom.start > disk.maxPartitionStartSector:
-            log.debug("free range start sector beyond max for new partitions")
-            continue
-
-        if boot:
-            free_start_mb = sectorsToSize(free_geom.start,
-                                          disk.device.sectorSize)
-            req_end_mb = free_start_mb + req_size
-            if req_end_mb > 2*1024*1024:
-                log.debug("free range position would place boot req above 2TB")
-                continue
-
-        log.debug("current free range is %d-%d (%dMB)" % (free_geom.start,
-                                                          free_geom.end,
-                                                          free_geom.getSize()))
-        free_size = free_geom.getSize()
-
-        # For boot partitions, we want the first suitable region we find.
-        # For growable or extended partitions, we want the largest possible
-        # free region.
-        # For all others, we want the smallest suitable free region.
-        if grow or part_type == parted.PARTITION_EXTENDED:
-            op = gt
-        else:
-            op = lt
-        if req_size <= free_size:
-            if not best_free or op(free_geom.length, best_free.length):
-                best_free = free_geom
-
-                if boot:
-                    # if this is a bootable partition we want to
-                    # use the first freespace region large enough
-                    # to satisfy the request
-                    break
-
-    return best_free
-
-def sectorsToSize(sectors, sectorSize):
-    """ Convert length in sectors to size in MB.
-
-        Arguments:
-
-            sectors     -   sector count
-            sectorSize  -   sector size for the device, in bytes
-    """
-    return (sectors * sectorSize) / (1024.0 * 1024.0)
-
-def sizeToSectors(size, sectorSize):
-    """ Convert size in MB to length in sectors.
-
-        Arguments:
-
-            size        -   size in MB
-            sectorSize  -   sector size for the device, in bytes
-    """
-    return (size * 1024.0 * 1024.0) / sectorSize
-
-def removeNewPartitions(disks, partitions):
-    """ Remove newly added input partitions from input disks.
-
-        Arguments:
-
-            disks -- list of StorageDevice instances with DiskLabel format
-            partitions -- list of PartitionDevice instances
-
-    """
-    log.debug("removing all non-preexisting partitions %s from disk(s) %s"
-                % (["%s(id %d)" % (p.name, p.id) for p in partitions
-                                                    if not p.exists],
-                   [d.name for d in disks]))
-    for part in partitions:
-        if part.partedPartition and part.disk in disks:
-            if part.exists:
-                # we're only removing partitions that don't physically exist
-                continue
-
-            if part.isExtended:
-                # these get removed last
-                continue
-
-            part.disk.format.partedDisk.removePartition(part.partedPartition)
-            part.partedPartition = None
-            part.disk = None
-
-    for disk in disks:
-        # remove empty extended so it doesn't interfere
-        extended = disk.format.extendedPartition
-        if extended and not disk.format.logicalPartitions:
-            log.debug("removing empty extended partition from %s" % disk.name)
-            disk.format.partedDisk.removePartition(extended)
-
-def addPartition(disklabel, free, part_type, size):
-    """ Return new partition after adding it to the specified disk.
-
-        Arguments:
-
-            disklabel -- disklabel instance to add partition to
-            free -- where to add the partition (parted.Geometry instance)
-            part_type -- partition type (parted.PARTITION_* constant)
-            size -- size (in MB) of the new partition
-
-        The new partition will be aligned.
-
-        Return value is a parted.Partition instance.
-
-    """
-    start = free.start
-    if not disklabel.alignment.isAligned(free, start):
-        start = disklabel.alignment.alignNearest(free, start)
-
-    if disklabel.labelType == "sun" and start == 0:
-        start = disklabel.alignment.alignUp(free, start)
-
-    if part_type == parted.PARTITION_LOGICAL:
-        # make room for logical partition's metadata
-        start += disklabel.alignment.grainSize
-
-    if start != free.start:
-        log.debug("adjusted start sector from %d to %d" % (free.start, start))
-
-    if part_type == parted.PARTITION_EXTENDED:
-        end = free.end
-        length = end - start + 1
-    else:
-        # size is in MB
-        length = sizeToSectors(size, disklabel.partedDevice.sectorSize)
-        end = start + length - 1
-
-    if not disklabel.endAlignment.isAligned(free, end):
-        end = disklabel.endAlignment.alignNearest(free, end)
-        log.debug("adjusted length from %d to %d" % (length, end - start + 1))
-        if start > end:
-            raise PartitioningError(_("unable to allocate aligned partition"))
-
-    new_geom = parted.Geometry(device=disklabel.partedDevice,
-                               start=start,
-                               end=end)
-
-    max_length = disklabel.partedDisk.maxPartitionLength
-    if max_length and new_geom.length > max_length:
-        raise PartitioningError(_("requested size exceeds maximum allowed"))
-
-    # create the partition and add it to the disk
-    partition = parted.Partition(disk=disklabel.partedDisk,
-                                 type=part_type,
-                                 geometry=new_geom)
-    constraint = parted.Constraint(exactGeom=new_geom)
-    disklabel.partedDisk.addPartition(partition=partition,
-                                      constraint=constraint)
-    return partition
-
-def getFreeRegions(disks):
-    """ Return a list of free regions on the specified disks.
-
-        Arguments:
-
-            disks -- list of parted.Disk instances
-
-        Return value is a list of unaligned parted.Geometry instances.
-
-    """
-    free = []
-    for disk in disks:
-        for f in disk.format.partedDisk.getFreeSpaceRegions():
-            if f.length > 0:
-                free.append(f)
-
-    return free
-
-def updateExtendedPartitions(storage, disks):
-    # XXX hack -- if we created any extended partitions we need to add
-    #             them to the tree now
-    for disk in disks:
-        extended = disk.format.extendedPartition
-        if not extended:
-            # remove any obsolete extended partitions
-            for part in storage.partitions:
-                if part.disk == disk and part.isExtended:
-                    if part.exists:
-                        storage.destroyDevice(part)
-                    else:
-                        storage.devicetree._removeDevice(part, moddisk=False)
-            continue
-
-        extendedName = devicePathToName(extended.getDeviceNodeName())
-        # remove any obsolete extended partitions
-        for part in storage.partitions:
-            if part.disk == disk and part.isExtended and \
-               part.partedPartition not in disk.format.partitions:
-                if part.exists:
-                    storage.destroyDevice(part)
-                else:
-                    storage.devicetree._removeDevice(part, moddisk=False)
-
-        device = storage.devicetree.getDeviceByName(extendedName)
-        if device:
-            if not device.exists:
-                # created by us, update partedPartition
-                device.partedPartition = extended
-            continue
-
-        # This is a little odd because normally instantiating a partition
-        # that does not exist means leaving self.parents empty and instead
-        # populating self.req_disks. In this case, we need to skip past
-        # that since this partition is already defined.
-        device = PartitionDevice(extendedName, parents=disk)
-        device.parents = [disk]
-        device.partedPartition = extended
-        # just add the device for now -- we'll handle actions at the last
-        # moment to simplify things
-        storage.devicetree._addDevice(device)
-
-def doPartitioning(storage):
-    """ Allocate and grow partitions.
-
-        When this function returns without error, all PartitionDevice
-        instances must have their parents set to the disk they are
-        allocated on, and their partedPartition attribute set to the
-        appropriate parted.Partition instance from their containing
-        disk. All req_xxxx attributes must be unchanged.
-
-        Arguments:
-
-            storage - Main anaconda Storage instance
-
-        Keyword/Optional Arguments:
-
-            None
-
-    """
-    disks = storage.partitioned
-    if storage.config.exclusiveDisks:
-        disks = [d for d in disks if d.name in storage.config.exclusiveDisks]
-
-    for disk in disks:
-        try:
-            disk.setup()
-        except DeviceError as (msg, name):
-            log.error("failed to set up disk %s: %s" % (name, msg))
-            raise PartitioningError(_("disk %s inaccessible") % disk.name)
-
-    partitions = storage.partitions[:]
-    for part in storage.partitions:
-        part.req_bootable = False
-
-        if part.exists:
-            # if the partition is preexisting or part of a complex device
-            # then we shouldn't modify it
-            partitions.remove(part)
-            continue
-
-        if not part.exists:
-            # start over with flexible-size requests
-            part.req_size = part.req_base_size
-
-    try:
-        storage.bootDevice.req_bootable = True
-    except AttributeError:
-        # there's no stage2 device. hopefully it's temporary.
-        pass
-
-    removeNewPartitions(disks, partitions)
-    free = getFreeRegions(disks)
-    try:
-        allocatePartitions(storage, disks, partitions, free)
-        growPartitions(disks, partitions, free, size_sets=storage.size_sets)
-    except Exception:
-        raise
-    else:
-        # Mark all growable requests as no longer growable.
-        for partition in storage.partitions:
-            log.debug("fixing size of %s at %.2f" % (partition, partition.size))
-            partition.req_grow = False
-            partition.req_base_size = partition.size
-            partition.req_size = partition.size
-    finally:
-        # these are only valid for one allocation run
-        storage.size_sets = []
-
-        # The number and thus the name of partitions may have changed now,
-        # allocatePartitions() takes care of this for new partitions, but not
-        # for pre-existing ones, so we update the name of all partitions here
-        for part in storage.partitions:
-            # leave extended partitions as-is -- we'll handle them separately
-            if part.isExtended:
-                continue
-            part.updateName()
-
-        updateExtendedPartitions(storage, disks)
-
-        for part in [p for p in storage.partitions if not p.exists]:
-            problem = part.checkSize()
-            if problem < 0:
-                raise PartitioningError(_("partition is too small for %(format)s formatting "
-                                        "(allowable size is %(minSize)d MB to %(maxSize)d MB)")
-                                        % {"format": part.format.name, "minSize": part.format.minSize,
-                                            "maxSize": part.format.maxSize})
-            elif problem > 0:
-                raise PartitioningError(_("partition is too large for %(format)s formatting "
-                                        "(allowable size is %(minSize)d MB to %(maxSize)d MB)")
-                                        % {"format": part.format.name, "minSize": part.format.minSize,
-                                            "maxSize": part.format.maxSize})
-
-def allocatePartitions(storage, disks, partitions, freespace):
-    """ Allocate partitions based on requested features.
-
-        Non-existing partitions are sorted according to their requested
-        attributes, and then allocated.
-
-        The basic approach to sorting is that the more specifically-
-        defined a request is, the earlier it will be allocated. See
-        the function partitionCompare for details on the sorting
-        criteria.
-
-        The PartitionDevice instances will have their name and parents
-        attributes set once they have been allocated.
-    """
-    log.debug("allocatePartitions: disks=%s ; partitions=%s" %
-                ([d.name for d in disks],
-                 ["%s(id %d)" % (p.name, p.id) for p in partitions]))
-
-    new_partitions = [p for p in partitions if not p.exists]
-    new_partitions.sort(cmp=partitionCompare)
-
-    # the following dicts all use device path strings as keys
-    disklabels = {}     # DiskLabel instances for each disk
-    all_disks = {}      # StorageDevice for each disk
-    for disk in disks:
-        if disk.path not in disklabels.keys():
-            disklabels[disk.path] = disk.format
-            all_disks[disk.path] = disk
-
-    removeNewPartitions(disks, new_partitions)
-
-    for _part in new_partitions:
-        if _part.partedPartition and _part.isExtended:
-            # ignore new extendeds as they are implicit requests
-            continue
-
-        # obtain the set of candidate disks
-        req_disks = []
-        if _part.req_disks:
-            # use the requested disk set
-            req_disks = _part.req_disks
-        else:
-            # no disks specified means any disk will do
-            req_disks = disks
-
-        # sort the disks, making sure the boot disk is first
-        req_disks.sort(key=lambda d: d.name, cmp=storage.compareDisks)
-        for disk in req_disks:
-            if storage.bootDisk and disk == storage.bootDisk:
-                boot_index = req_disks.index(disk)
-                req_disks.insert(0, req_disks.pop(boot_index))
-
-        boot = _part.req_base_weight > 1000
-
-        log.debug("allocating partition: %s ; id: %d ; disks: %s ;\n"
-                  "boot: %s ; primary: %s ; size: %dMB ; grow: %s ; "
-                  "max_size: %s" % (_part.name, _part.id,
-                                    [d.name for d in req_disks],
-                                    boot, _part.req_primary,
-                                    _part.req_size, _part.req_grow,
-                                    _part.req_max_size))
-        free = None
-        use_disk = None
-        part_type = None
-        growth = 0
-        # loop through disks
-        for _disk in req_disks:
-            disklabel = disklabels[_disk.path]
-            sectorSize = disklabel.partedDevice.sectorSize
-            best = None
-            current_free = free
-
-            # for growable requests, we don't want to pass the current free
-            # geometry to getBestFreeRegion -- this allows us to try the
-            # best region from each disk and choose one based on the total
-            # growth it allows
-            if _part.req_grow:
-                current_free = None
-
-            log.debug("checking freespace on %s" % _disk.name)
-
-            new_part_type = getNextPartitionType(disklabel.partedDisk)
-            if new_part_type is None:
-                # can't allocate any more partitions on this disk
-                log.debug("no free partition slots on %s" % _disk.name)
-                continue
-
-            if _part.req_primary and new_part_type != parted.PARTITION_NORMAL:
-                if (disklabel.partedDisk.primaryPartitionCount <
-                    disklabel.partedDisk.maxPrimaryPartitionCount):
-                    # don't fail to create a primary if there are only three
-                    # primary partitions on the disk (#505269)
-                    new_part_type = parted.PARTITION_NORMAL
-                else:
-                    # we need a primary slot and none are free on this disk
-                    log.debug("no primary slots available on %s" % _disk.name)
-                    continue
-
-            best = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                          new_part_type,
-                                          _part.req_size,
-                                          best_free=current_free,
-                                          boot=boot,
-                                          grow=_part.req_grow)
-
-            if best == free and not _part.req_primary and \
-               new_part_type == parted.PARTITION_NORMAL:
-                # see if we can do better with a logical partition
-                log.debug("not enough free space for primary -- trying logical")
-                new_part_type = getNextPartitionType(disklabel.partedDisk,
-                                                     no_primary=True)
-                if new_part_type:
-                    best = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                                  new_part_type,
-                                                  _part.req_size,
-                                                  best_free=current_free,
-                                                  boot=boot,
-                                                  grow=_part.req_grow)
-
-            if best and free != best:
-                update = True
-                allocated = new_partitions[:new_partitions.index(_part)+1]
-                if any([p.req_grow for p in allocated]):
-                    log.debug("evaluating growth potential for new layout")
-                    new_growth = 0
-                    for disk_path in disklabels.keys():
-                        log.debug("calculating growth for disk %s" % disk_path)
-                        # Now we check, for growable requests, which of the two
-                        # free regions will allow for more growth.
-
-                        # set up chunks representing the disks' layouts
-                        temp_parts = []
-                        for _p in new_partitions[:new_partitions.index(_part)]:
-                            if _p.disk.path == disk_path:
-                                temp_parts.append(_p)
-
-                        # add the current request to the temp disk to set up
-                        # its partedPartition attribute with a base geometry
-                        if disk_path == _disk.path:
-                            _part_type = new_part_type
-                            _free = best
-                            if new_part_type == parted.PARTITION_EXTENDED:
-                                addPartition(disklabel, best, new_part_type,
-                                             None)
-
-                                _part_type = parted.PARTITION_LOGICAL
-
-                                _free = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                                               _part_type,
-                                                               _part.req_size,
-                                                               boot=boot,
-                                                               grow=_part.req_grow)
-                                if not _free:
-                                    log.info("not enough space after adding "
-                                             "extended partition for growth test")
-                                    if new_part_type == parted.PARTITION_EXTENDED:
-                                        e = disklabel.extendedPartition
-                                        disklabel.partedDisk.removePartition(e)
-
-                                    continue
-
-                            temp_part = addPartition(disklabel,
-                                                     _free,
-                                                     _part_type,
-                                                     _part.req_size)
-                            _part.partedPartition = temp_part
-                            _part.disk = _disk
-                            temp_parts.append(_part)
-
-                        chunks = getDiskChunks(all_disks[disk_path],
-                                               temp_parts, freespace)
-
-                        # grow all growable requests
-                        disk_growth = 0
-                        disk_sector_size = disklabels[disk_path].partedDevice.sectorSize
-                        for chunk in chunks:
-                            chunk.growRequests()
-                            # record the growth for this layout
-                            new_growth += chunk.growth
-                            disk_growth += chunk.growth
-                            for req in chunk.requests:
-                                log.debug("request %d (%s) growth: %d (%dMB) "
-                                          "size: %dMB" %
-                                          (req.device.id,
-                                           req.device.name,
-                                           req.growth,
-                                           sectorsToSize(req.growth,
-                                                         disk_sector_size),
-                                           sectorsToSize(req.growth + req.base,
-                                                         disk_sector_size)))
-                        log.debug("disk %s growth: %d (%dMB)" %
-                                        (disk_path, disk_growth,
-                                         sectorsToSize(disk_growth,
-                                                       disk_sector_size)))
-
-                    disklabel.partedDisk.removePartition(temp_part)
-                    _part.partedPartition = None
-                    _part.disk = None
-
-                    if new_part_type == parted.PARTITION_EXTENDED:
-                        e = disklabel.extendedPartition
-                        disklabel.partedDisk.removePartition(e)
-
-                    log.debug("total growth: %d sectors" % new_growth)
-
-                    # update the chosen free region unless the previous
-                    # choice yielded greater total growth
-                    if free is not None and new_growth <= growth:
-                        log.debug("keeping old free: %d <= %d" % (new_growth,
-                                                                  growth))
-                        update = False
-                    else:
-                        growth = new_growth
-
-                if update:
-                    # now we know we are choosing a new free space,
-                    # so update the disk and part type
-                    log.debug("updating use_disk to %s, type: %s"
-                                % (_disk.name, new_part_type))
-                    part_type = new_part_type
-                    use_disk = _disk
-                    log.debug("new free: %d-%d / %dMB" % (best.start,
-                                                          best.end,
-                                                          best.getSize()))
-                    log.debug("new free allows for %d sectors of growth" %
-                                growth)
-                    free = best
-
-            if free and boot:
-                # if this is a bootable partition we want to
-                # use the first freespace region large enough
-                # to satisfy the request
-                log.debug("found free space for bootable request")
-                break
-
-        if free is None:
-            raise PartitioningError(_("not enough free space on disks"))
-
-        _disk = use_disk
-        disklabel = _disk.format
-
-        # create the extended partition if needed
-        if part_type == parted.PARTITION_EXTENDED:
-            log.debug("creating extended partition")
-            addPartition(disklabel, free, part_type, None)
-
-            # now the extended partition exists, so set type to logical
-            part_type = parted.PARTITION_LOGICAL
-
-            # recalculate freespace
-            log.debug("recalculating free space")
-            free = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                          part_type,
-                                          _part.req_size,
-                                          boot=boot,
-                                          grow=_part.req_grow)
-            if not free:
-                raise PartitioningError(_("not enough free space after "
-                                        "creating extended partition"))
-
-        partition = addPartition(disklabel, free, part_type, _part.req_size)
-        log.debug("created partition %s of %dMB and added it to %s" %
-                (partition.getDeviceNodeName(), partition.getSize(),
-                 disklabel.device))
-
-        # this one sets the name
-        _part.partedPartition = partition
-        _part.disk = _disk
-
-        # parted modifies the partition in the process of adding it to
-        # the disk, so we need to grab the latest version...
-        _part.partedPartition = disklabel.partedDisk.getPartitionByPath(_part.path)
-
-
-class Request(object):
-    """ A partition request.
-
-        Request instances are used for calculating how much to grow
-        partitions.
-    """
-    def __init__(self, device):
-        """ Create a Request instance.
-
-            Arguments:
-
-        """
-        self.device = device
-        self.growth = 0                     # growth in sectors
-        self.max_growth = 0                 # max growth in sectors
-        self.done = not getattr(device, "req_grow", True)  # can we grow this
-                                                           # request more?
-        self.base = 0                       # base sectors
-
-    @property
-    def growable(self):
-        """ True if this request is growable. """
-        return getattr(self.device, "req_grow", True)
-
-    @property
-    def id(self):
-        """ The id of the Device instance this request corresponds to. """
-        return self.device.id
-
-    def __repr__(self):
-        s = ("%(type)s instance --\n"
-             "id = %(id)s  name = %(name)s  growable = %(growable)s\n"
-             "base = %(base)d  growth = %(growth)d  max_grow = %(max_grow)d\n"
-             "done = %(done)s" %
-             {"type": self.__class__.__name__, "id": self.id,
-              "name": self.device.name, "growable": self.growable,
-              "base": self.base, "growth": self.growth,
-              "max_grow": self.max_growth, "done": self.done})
-        return s
-
-
-class PartitionRequest(Request):
-    def __init__(self, partition):
-        """ Create a PartitionRequest instance.
-
-            Arguments:
-
-                partition -- a PartitionDevice instance
-
-        """
-        super(PartitionRequest, self).__init__(partition)
-        self.base = partition.partedPartition.geometry.length   # base sectors
-
-        sector_size = partition.partedPartition.disk.device.sectorSize
-
-        if partition.req_grow:
-            limits = filter(lambda l: l > 0,
-                        [sizeToSectors(partition.req_max_size, sector_size),
-                         sizeToSectors(partition.format.maxSize, sector_size),
-                         partition.partedPartition.disk.maxPartitionLength])
-
-            if limits:
-                max_sectors = min(limits)
-                self.max_growth = max_sectors - self.base
-                if self.max_growth <= 0:
-                    # max size is less than or equal to base, so we're done
-                    self.done = True
-
-
-class LVRequest(Request):
-    def __init__(self, lv):
-        """ Create a LVRequest instance.
-
-            Arguments:
-
-                lv -- an LVMLogicalVolumeDevice instance
-
-        """
-        super(LVRequest, self).__init__(lv)
-
-        # Round up to nearest pe. For growable requests this will mean that
-        # first growth is to fill the remainder of any unused extent.
-        self.base = lv.vg.align(lv.req_size, roundup=True) / lv.vg.peSize # pe
-
-        if lv.req_grow:
-            limits = [l / lv.vg.peSize for l in
-                        [lv.vg.align(lv.req_max_size),
-                         lv.vg.align(lv.format.maxSize)] if l > 0]
-
-            if limits:
-                max_units = min(limits)
-                self.max_growth = max_units - self.base
-                if self.max_growth <= 0:
-                    # max size is less than or equal to base, so we're done
-                    self.done = True
-
-
-class Chunk(object):
-    """ A free region from which devices will be allocated """
-    def __init__(self, length, requests=None):
-        """ Create a Chunk instance.
-
-            Arguments:
-
-                length -- the length of the chunk in allocation units
-
-
-            Keyword Arguments:
-
-                requests -- list of Request instances allocated from this chunk
-
-        """
-        if not hasattr(self, "path"):
-            self.path = None
-        self.length = length
-        self.pool = length                  # free unit count
-        self.base = 0                       # sum of growable requests' base
-                                            # sizes
-        self.requests = []                  # list of Request instances
-        if isinstance(requests, list):
-            for req in requests:
-                self.addRequest(req)
-
-        self.skip_list = []
-
-    def __repr__(self):
-        s = ("%(type)s instance --\n"
-             "device = %(device)s  length = %(length)d  size = %(size)d\n"
-             "remaining = %(rem)d  pool = %(pool)d" %
-             {"type": self.__class__.__name__, "device": self.path,
-              "length": self.length, "size": self.lengthToSize(self.length),
-              "pool": self.pool, "rem": self.remaining})
-
-        return s
-
-    def __str__(self):
-        s = "%d on %s" % (self.length, self.path)
-        return s
-
-    def addRequest(self, req):
-        """ Add a Request to this chunk. """
-        log.debug("adding request %d to chunk %s" % (req.device.id, self))
-
-        self.requests.append(req)
-        self.pool -= req.base
-
-        if not req.done:
-            self.base += req.base
-
-    def reclaim(self, request, amount):
-        """ Reclaim units from a request and return them to the pool. """
-        log.debug("reclaim: %s %d (%d MB)" % (request, amount, self.lengthToSize(amount)))
-        if request.growth < amount:
-            log.error("tried to reclaim %d from request with %d of growth"
-                        % (amount, request.growth))
-            raise ValueError(_("cannot reclaim more than request has grown"))
-
-        request.growth -= amount
-        self.pool += amount
-
-        # put this request in the skip list so we don't try to grow it the
-        # next time we call growRequests to allocate the newly re-acquired pool
-        if request not in self.skip_list:
-            self.skip_list.append(request)
-
-    @property
-    def growth(self):
-        """ Sum of growth for all requests in this chunk. """
-        return sum(r.growth for r in self.requests)
-
-    @property
-    def hasGrowable(self):
-        """ True if this chunk contains at least one growable request. """
-        for req in self.requests:
-            if req.growable:
-                return True
-        return False
-
-    @property
-    def remaining(self):
-        """ Number of requests still being grown in this chunk. """
-        return len([d for d in self.requests if not d.done])
-
-    @property
-    def done(self):
-        """ True if we are finished growing all requests in this chunk. """
-        return self.remaining == 0
-
-    def maxGrowth(self, req):
-        return req.max_growth
-
-    def lengthToSize(self, length):
-        return length
-
-    def sizeToLength(self, size):
-        return size
-
-    def trimOverGrownRequest(self, req, base=None):
-        """ Enforce max growth and return extra units to the pool. """
-        max_growth = self.maxGrowth(req)
-        if max_growth and req.growth >= max_growth:
-            if req.growth > max_growth:
-                # we've grown beyond the maximum. put some back.
-                extra = req.growth - max_growth
-                log.debug("taking back %d (%dMB) from %d (%s)" %
-                            (extra, self.lengthToSize(extra),
-                             req.device.id, req.device.name))
-                self.pool += extra
-                req.growth = max_growth
-
-            # We're done growing this request, so it no longer
-            # factors into the growable base used to determine
-            # what fraction of the pool each request gets.
-            if base is not None:
-                base -= req.base
-            req.done = True
-
-        return base
-
-    def sortRequests(self):
-        pass
-
-    def growRequests(self, uniform=False):
-        """ Calculate growth amounts for requests in this chunk. """
-        log.debug("Chunk.growRequests: %r" % self)
-
-        self.sortRequests()
-        for req in self.requests:
-            log.debug("req: %r" % req)
-
-        # we use this to hold the base for the next loop through the
-        # chunk's requests since we want the base to be the same for
-        # all requests in any given growth iteration
-        new_base = self.base
-        last_pool = 0 # used to track changes to the pool across iterations
-        while not self.done and self.pool and last_pool != self.pool:
-            last_pool = self.pool    # to keep from getting stuck
-            self.base = new_base
-            if uniform:
-                growth = last_pool / self.remaining
-
-            log.debug("%d requests and %d (%dMB) left in chunk" %
-                        (self.remaining, self.pool, self.lengthToSize(self.pool)))
-            for p in self.requests:
-                if p.done or p in self.skip_list:
-                    continue
-
-                if not uniform:
-                    # Each request is allocated free units from the pool
-                    # based on the relative _base_ sizes of the remaining
-                    # growable requests.
-                    share = p.base / float(self.base)
-                    growth = int(share * last_pool) # truncate, don't round
-
-                p.growth += growth
-                self.pool -= growth
-                log.debug("adding %d (%dMB) to %d (%s)" %
-                            (growth, self.lengthToSize(growth),
-                             p.device.id, p.device.name))
-
-                new_base = self.trimOverGrownRequest(p, base=new_base)
-                log.debug("new grow amount for request %d (%s) is %d "
-                          "units, or %dMB" %
-                            (p.device.id, p.device.name, p.growth,
-                             self.lengthToSize(p.growth)))
-
-        if self.pool:
-            # allocate any leftovers in pool to the first partition
-            # that can still grow
-            for p in self.requests:
-                if p.done:
-                    continue
-
-                growth = self.pool
-                p.growth += growth
-                self.pool = 0
-                log.debug("adding %d (%dMB) to %d (%s)" %
-                            (growth, self.lengthToSize(growth),
-                             p.device.id, p.device.name))
-
-                self.trimOverGrownRequest(p)
-                log.debug("new grow amount for request %d (%s) is %d "
-                          "units, or %dMB" %
-                            (p.device.id, p.device.name, p.growth,
-                             self.lengthToSize(p.growth)))
-
-                if self.pool == 0:
-                    break
-
-        # requests that were skipped over this time through are back on the
-        # table next time
-        self.skip_list = []
-
-
-class DiskChunk(Chunk):
-    """ A free region on disk from which partitions will be allocated """
-    def __init__(self, geometry, requests=None):
-        """ Create a Chunk instance.
-
-            Arguments:
-
-                geometry -- parted.Geometry instance describing the free space
-
-
-            Keyword Arguments:
-
-                requests -- list of Request instances allocated from this chunk
-
-
-            Note: We will limit partition growth based on disklabel
-            limitations for partition end sector, so a 10TB disk with an
-            msdos disklabel will be treated like a 2TB disk.
-
-        """
-        self.geometry = geometry            # parted.Geometry
-        self.sectorSize = self.geometry.device.sectorSize
-        self.path = self.geometry.device.path
-        super(DiskChunk, self).__init__(self.geometry.length, requests=requests)
-
-    def __repr__(self):
-        s = super(DiskChunk, self).__str__()
-        s += (" start = %(start)d  end = %(end)d\n"
-              "sectorSize = %(sectorSize)d\n" %
-              {"start": self.geometry.start, "end": self.geometry.end,
-               "sectorSize": self.sectorSize})
-        return s
-
-    def __str__(self):
-        s = "%d (%d-%d) on %s" % (self.length, self.geometry.start,
-                                  self.geometry.end, self.path)
-        return s
-
-    def addRequest(self, req):
-        """ Add a Request to this chunk. """
-        if not isinstance(req, PartitionRequest):
-            raise ValueError(_("DiskChunk requests must be of type "
-                             "PartitionRequest"))
-
-        if not self.requests:
-            # when adding the first request to the chunk, adjust the pool
-            # size to reflect any disklabel-specific limits on end sector
-            max_sector = req.device.partedPartition.disk.maxPartitionStartSector
-            chunk_end = min(max_sector, self.geometry.end)
-            if chunk_end <= self.geometry.start:
-                # this should clearly never be possible, but if the chunk's
-                # start sector is beyond the maximum allowed end sector, we
-                # cannot continue
-                log.error("chunk start sector is beyond disklabel maximum")
-                raise PartitioningError(_("partitions allocated outside "
-                                        "disklabel limits"))
-
-            new_pool = chunk_end - self.geometry.start + 1
-            if new_pool != self.pool:
-                log.debug("adjusting pool to %d based on disklabel limits"
-                            % new_pool)
-                self.pool = new_pool
-
-        super(DiskChunk, self).addRequest(req)
-
-    def maxGrowth(self, req):
-        req_end = req.device.partedPartition.geometry.end
-        req_start = req.device.partedPartition.geometry.start
-
-        # Establish the current total number of sectors of growth for requests
-        # that lie before this one within this chunk. We add the total count
-        # to this request's end sector to obtain the end sector for this
-        # request, including growth of earlier requests but not including
-        # growth of this request. Maximum growth values are obtained using
-        # this end sector and various values for maximum end sector.
-        growth = 0
-        for request in self.requests:
-            if request.device.partedPartition.geometry.start < req_start:
-                growth += request.growth
-        req_end += growth
-
-        # obtain the set of possible maximum sectors-of-growth values for this
-        # request and use the smallest
-        limits = []
-
-        # disklabel-specific maximum sector
-        max_sector = req.device.partedPartition.disk.maxPartitionStartSector
-        limits.append(max_sector - req_end)
-
-        # 2TB limit on bootable partitions, regardless of disklabel
-        if req.device.req_bootable:
-            limits.append(sizeToSectors(2*1024*1024, self.sectorSize) - req_end)
-
-        # request-specific maximum (see Request.__init__, above, for details)
-        if req.max_growth:
-            limits.append(req.max_growth)
-
-        max_growth = min(limits)
-        return max_growth
-
-    def lengthToSize(self, length):
-        return sectorsToSize(length, self.sectorSize)
-
-    def sizeToLength(self, size):
-        return sizeToSectors(size, self.sectorSize)
-
-    def sortRequests(self):
-        # sort the partitions by start sector
-        self.requests.sort(key=lambda r: r.device.partedPartition.geometry.start)
-
-
-class VGChunk(Chunk):
-    """ A free region in an LVM VG from which LVs will be allocated """
-    def __init__(self, vg, requests=None):
-        """ Create a VGChunk instance.
-
-            Arguments:
-
-                vg -- an LVMVolumeGroupDevice within which this chunk resides
-
-
-            Keyword Arguments:
-
-                requests -- list of Request instances allocated from this chunk
-
-        """
-        self.vg = vg
-        self.path = vg.path
-        usable_extents = vg.extents - (vg.reservedSpace / vg.peSize)
-        super(VGChunk, self).__init__(usable_extents, requests=requests)
-
-    def addRequest(self, req):
-        """ Add a Request to this chunk. """
-        if not isinstance(req, LVRequest):
-            raise ValueError(_("VGChunk requests must be of type "
-                             "LVRequest"))
-
-        super(VGChunk, self).addRequest(req)
-
-    def lengthToSize(self, length):
-        return length * self.vg.peSize
-
-    def sizeToLength(self, size):
-        return size / self.vg.peSize
-
-    def sortRequests(self):
-        # sort the partitions by start sector
-        self.requests.sort(key=lambda r: r.device, cmp=lvCompare)
-
-    def growRequests(self):
-        self.sortRequests()
-
-        # grow the percentage-based requests
-        last_pool = self.pool
-        for req in self.requests:
-            if req.done or not req.device.req_percent:
-                continue
-
-            growth = int(req.device.req_percent * 0.01 * self.length)# truncate
-            req.growth += growth
-            self.pool -= growth
-            log.debug("adding %d (%dMB) to %d (%s)" %
-                        (growth, self.lengthToSize(growth),
-                         req.device.id, req.device.name))
-
-            new_base = self.trimOverGrownRequest(req)
-            log.debug("new grow amount for request %d (%s) is %d "
-                      "units, or %dMB" %
-                        (req.device.id, req.device.name, req.growth,
-                         self.lengthToSize(req.growth)))
-
-            # we're done with this request, so remove its base from the
-            # chunk's base
-            if not req.done:
-                self.base -= req.base
-                req.done = True
-
-        super(VGChunk, self).growRequests()
-
-
-def getDiskChunks(disk, partitions, free):
-    """ Return a list of Chunk instances representing a disk.
-
-        Arguments:
-
-            disk -- a StorageDevice with a DiskLabel format
-            partitions -- list of PartitionDevice instances
-            free -- list of parted.Geometry instances representing free space
-
-        Partitions and free regions not on the specified disk are ignored.
-
-    """
-    # list of all new partitions on this disk
-    disk_parts = [p for p in partitions if p.disk == disk and not p.exists]
-    disk_free = [f for f in free if f.device.path == disk.path]
-
-
-    chunks = [DiskChunk(f) for f in disk_free]
-
-    for p in disk_parts:
-        if p.isExtended:
-            # handle extended partitions specially since they are
-            # indeed very special
-            continue
-
-        for i, f in enumerate(disk_free):
-            if f.contains(p.partedPartition.geometry):
-                chunks[i].addRequest(PartitionRequest(p))
-                break
-
-    return chunks
-
-class TotalSizeSet(object):
-    """ Set of device requests with a target combined size.
-
-        This will be handled by growing the requests until the desired combined
-        size has been achieved.
-    """
-    def __init__(self, devices, size):
-        self.devices = []
-        for device in devices:
-            if isinstance(device, LUKSDevice):
-                partition = device.slave
-            else:
-                partition = device
-
-            self.devices.append(partition)
-
-        self.size = size
-
-        self.requests = []
-
-        self.allocated = sum([d.req_base_size for d in self.devices])
-        log.debug("set.allocated = %d" % self.allocated)
-
-    def allocate(self, amount):
-        log.debug("allocating %d to TotalSizeSet with %d/%d (%d needed)"
-                    % (amount, self.allocated, self.size, self.needed))
-        self.allocated += amount
-
-    @property
-    def needed(self):
-        return self.size - self.allocated
-
-    def deallocate(self, amount):
-        log.debug("deallocating %d from TotalSizeSet with %d/%d (%d needed)"
-                    % (amount, self.allocated, self.size, self.needed))
-        self.allocated -= amount
-
-class SameSizeSet(object):
-    """ Set of device requests with a common target size. """
-    def __init__(self, devices, size, grow=False, max_size=None):
-        self.devices = []
-        for device in devices:
-            if isinstance(device, LUKSDevice):
-                partition = device.slave
-            else:
-                partition = device
-
-            self.devices.append(partition)
-
-        self.size = int(size / len(devices))
-        self.grow = grow
-        self.max_size = max_size
-
-        self.requests = []
-
-def manageSizeSets(size_sets, chunks):
-    growth_by_request = {}
-    requests_by_device = {}
-    chunks_by_request = {}
-    for chunk in chunks:
-        for request in chunk.requests:
-            requests_by_device[request.device] = request
-            chunks_by_request[request] = chunk
-            growth_by_request[request] = 0
-
-    for i in range(2):
-        reclaimed = dict([(chunk, 0) for chunk in chunks])
-        for ss in size_sets:
-            if isinstance(ss, TotalSizeSet):
-                # TotalSizeSet members are trimmed to achieve the requested
-                # total size
-                log.debug("set: %s %d/%d" % ([d.name for d in ss.devices],
-                                              ss.allocated, ss.size))
-
-                for device in ss.devices:
-                    request = requests_by_device[device]
-                    chunk = chunks_by_request[request]
-                    new_growth = request.growth - growth_by_request[request]
-                    ss.allocate(chunk.lengthToSize(new_growth))
-
-                # decide how much to take back from each request
-                # We may assume that all requests have the same base size.
-                # We're shooting for a roughly equal distribution by trimming
-                # growth from the requests that have grown the most first.
-                requests = sorted([requests_by_device[d] for d in ss.devices],
-                                  key=lambda r: r.growth, reverse=True)
-                needed = ss.needed
-                for request in requests:
-                    chunk = chunks_by_request[request]
-                    log.debug("%s" % request)
-                    log.debug("needed: %d" % ss.needed)
-
-                    if ss.needed < 0:
-                        # it would be good to take back some from each device
-                        # instead of taking all from the last one(s)
-                        extra = -chunk.sizeToLength(needed) / len(ss.devices)
-                        if extra > request.growth and i == 0:
-                            log.debug("not reclaiming from this request")
-                            continue
-                        else:
-                            extra = min(extra, request.growth)
-
-                        reclaimed[chunk] += extra
-                        chunk.reclaim(request, extra)
-                        ss.deallocate(chunk.lengthToSize(extra))
-
-                    if ss.needed <= 0:
-                        request.done = True
-
-            elif isinstance(ss, SameSizeSet):
-                # SameSizeSet members all have the same size as the smallest
-                # member
-                requests = [requests_by_device[d] for d in ss.devices]
-                _min_growth = min([r.growth for r in requests])
-                log.debug("set: %s %d" % ([d.name for d in ss.devices], ss.size))
-                log.debug("min growth is %d" % _min_growth)
-                for request in requests:
-                    chunk = chunks_by_request[request]
-                    _max_growth = chunk.sizeToLength(ss.size) - request.base
-                    log.debug("max growth for %s is %d" % (request, _max_growth))
-                    min_growth = max(min(_min_growth, _max_growth), 0)
-                    if request.growth > min_growth:
-                        extra = request.growth - min_growth
-                        reclaimed[chunk] += extra
-                        chunk.reclaim(request, extra)
-                        request.done = True
-                    elif request.growth == min_growth:
-                        request.done = True
-
-        # store previous growth amounts so we know how much was allocated in
-        # the latest growRequests call
-        for request in growth_by_request.keys():
-            growth_by_request[request] = request.growth
-
-        for chunk in chunks:
-            if reclaimed[chunk] and not chunk.done:
-                chunk.growRequests()
-
-def growPartitions(disks, partitions, free, size_sets=None):
-    """ Grow all growable partition requests.
-
-        Partitions have already been allocated from chunks of free space on
-        the disks. This function does not modify the ordering of partitions
-        or the free chunks from which they are allocated.
-
-        Free space within a given chunk is allocated to each growable
-        partition allocated from that chunk in an amount corresponding to
-        the ratio of that partition's base size to the sum of the base sizes
-        of all growable partitions allocated from the chunk.
-
-        Arguments:
-
-            disks -- a list of all usable disks (DiskDevice instances)
-            partitions -- a list of all partitions (PartitionDevice instances)
-            free -- a list of all free regions (parted.Geometry instances)
-    """
-    log.debug("growPartitions: disks=%s, partitions=%s" %
-            ([d.name for d in disks],
-             ["%s(id %d)" % (p.name, p.id) for p in partitions]))
-    all_growable = [p for p in partitions if p.req_grow]
-    if not all_growable:
-        log.debug("no growable partitions")
-        return
-
-    if size_sets is None:
-        size_sets = []
-
-    log.debug("growable partitions are %s" % [p.name for p in all_growable])
-
-    #
-    # collect info about each disk and the requests it contains
-    #
-    chunks = []
-    for disk in disks:
-        sector_size = disk.format.partedDevice.sectorSize
-
-        # list of free space regions on this disk prior to partition allocation
-        disk_free = [f for f in free if f.device.path == disk.path]
-        if not disk_free:
-            log.debug("no free space on %s" % disk.name)
-            continue
-
-        disk_chunks = getDiskChunks(disk, partitions, disk_free)
-        log.debug("disk %s has %d chunks" % (disk.name, len(disk_chunks)))
-        chunks.extend(disk_chunks)
-
-    #
-    # grow the partitions in each chunk as a group
-    #
-    for chunk in chunks:
-        if not chunk.hasGrowable:
-            # no growable partitions in this chunk
-            continue
-
-        chunk.growRequests()
-
-    # adjust set members' growth amounts as needed
-    manageSizeSets(size_sets, chunks)
-
-    for disk in disks:
-        log.debug("growing partitions on %s" % disk.name)
-        for chunk in chunks:
-            if chunk.path != disk.path:
-                continue
-
-            if not chunk.hasGrowable:
-                # no growable partitions in this chunk
-                continue
-
-            # recalculate partition geometries
-            disklabel = disk.format
-            start = chunk.geometry.start
-
-            # find any extended partition on this disk
-            extended_geometry = getattr(disklabel.extendedPartition,
-                                        "geometry",
-                                        None)  # parted.Geometry
-
-            # align start sector as needed
-            if not disklabel.alignment.isAligned(chunk.geometry, start):
-                start = disklabel.alignment.alignUp(chunk.geometry, start)
-            new_partitions = []
-            for p in chunk.requests:
-                ptype = p.device.partedPartition.type
-                log.debug("partition %s (%d): %s" % (p.device.name,
-                                                     p.device.id, ptype))
-                if ptype == parted.PARTITION_EXTENDED:
-                    continue
-
-                # XXX since we need one metadata sector before each
-                #     logical partition we burn one logical block to
-                #     safely align the start of each logical partition
-                if ptype == parted.PARTITION_LOGICAL:
-                    start += disklabel.alignment.grainSize
-
-                old_geometry = p.device.partedPartition.geometry
-                new_length = p.base + p.growth
-                end = start + new_length - 1
-                # align end sector as needed
-                if not disklabel.endAlignment.isAligned(chunk.geometry, end):
-                    end = disklabel.endAlignment.alignDown(chunk.geometry, end)
-                new_geometry = parted.Geometry(device=disklabel.partedDevice,
-                                               start=start,
-                                               end=end)
-                log.debug("new geometry for %s: %s" % (p.device.name,
-                                                       new_geometry))
-                start = end + 1
-                new_partition = parted.Partition(disk=disklabel.partedDisk,
-                                                 type=ptype,
-                                                 geometry=new_geometry)
-                new_partitions.append((new_partition, p.device))
-
-            # remove all new partitions from this chunk
-            removeNewPartitions([disk], [r.device for r in chunk.requests])
-            log.debug("back from removeNewPartitions")
-
-            # adjust the extended partition as needed
-            # we will ony resize an extended partition that we created
-            log.debug("extended: %s" % extended_geometry)
-            if extended_geometry and \
-               chunk.geometry.contains(extended_geometry):
-                log.debug("setting up new geometry for extended on %s" % disk.name)
-                ext_start = 0
-                for (partition, device) in new_partitions:
-                    if partition.type != parted.PARTITION_LOGICAL:
-                        continue
-
-                    if not ext_start or partition.geometry.start < ext_start:
-                        # account for the logical block difference in start
-                        # sector for the extended -v- first logical
-                        # (partition.geometry.start is already aligned)
-                        ext_start = partition.geometry.start - disklabel.alignment.grainSize
-
-                new_geometry = parted.Geometry(device=disklabel.partedDevice,
-                                               start=ext_start,
-                                               end=chunk.geometry.end)
-                log.debug("new geometry for extended: %s" % new_geometry)
-                new_extended = parted.Partition(disk=disklabel.partedDisk,
-                                                type=parted.PARTITION_EXTENDED,
-                                                geometry=new_geometry)
-                ptypes = [p.type for (p, d) in new_partitions]
-                for pt_idx, ptype in enumerate(ptypes):
-                    if ptype == parted.PARTITION_LOGICAL:
-                        new_partitions.insert(pt_idx, (new_extended, None))
-                        break
-
-            # add the partitions with their new geometries to the disk
-            for (partition, device) in new_partitions:
-                if device:
-                    name = device.name
-                else:
-                    # If there was no extended partition on this disk when
-                    # doPartitioning was called we won't have a
-                    # PartitionDevice instance for it.
-                    name = partition.getDeviceNodeName()
-
-                log.debug("setting %s new geometry: %s" % (name,
-                                                           partition.geometry))
-                constraint = parted.Constraint(exactGeom=partition.geometry)
-                disklabel.partedDisk.addPartition(partition=partition,
-                                                  constraint=constraint)
-                path = partition.path
-                if device:
-                    # set the device's name
-                    device.partedPartition = partition
-                    # without this, the path attr will be a basename. eek.
-                    device.disk = disk
-
-                    # make sure we store the disk's version of the partition
-                    newpart = disklabel.partedDisk.getPartitionByPath(path)
-                    device.partedPartition = newpart
-
-
-def lvCompare(lv1, lv2):
-    """ More specifically defined lvs come first.
-
-        < 1 => x < y
-          0 => x == y
-        > 1 => x > y
-    """
-    ret = 0
-
-    # larger requests go to the front of the list
-    ret -= cmp(lv1.size, lv2.size) * 100
-
-    # fixed size requests to the front
-    ret += cmp(lv1.req_grow, lv2.req_grow) * 50
-
-    # potentially larger growable requests go to the front
-    if lv1.req_grow and lv2.req_grow:
-        if not lv1.req_max_size and lv2.req_max_size:
-            ret -= 25
-        elif lv1.req_max_size and not lv2.req_max_size:
-            ret += 25
-        else:
-            ret -= cmp(lv1.req_max_size, lv2.req_max_size) * 25
-
-    if ret > 0:
-        ret = 1
-    elif ret < 0:
-        ret = -1
-
-    return ret
-
-def growLVM(storage):
-    """ Grow LVs according to the sizes of the PVs. """
-    for vg in storage.vgs:
-        total_free = vg.freeSpace
-        if total_free < 0:
-            # by now we have allocated the PVs so if there isn't enough
-            # space in the VG we have a real problem
-            raise PartitioningError(_("not enough space for LVM requests"))
-        elif not total_free:
-            log.debug("vg %s has no free space" % vg.name)
-            continue
-
-        log.debug("vg %s: %dMB free ; lvs: %s" % (vg.name, total_free,
-                                                  [l.lvname for l in vg.lvs]))
-
-        chunk = VGChunk(vg, requests=[LVRequest(l) for l in vg.lvs])
-        chunk.growRequests()
-
-        # now grow the lvs by the amounts we've calculated above
-        for req in chunk.requests:
-            if not req.device.req_grow:
-                continue
-
-            # Base is in pe, which means potentially rounded up by as much as
-            # pesize-1. As a result, you can't just add the growth to the
-            # initial size.
-            req.device.size = chunk.lengthToSize(req.base + req.growth)
diff --git a/pyanaconda/storage/partspec.py b/pyanaconda/storage/partspec.py
deleted file mode 100644
index 97cb33e..0000000
--- a/pyanaconda/storage/partspec.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# partspec.py
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Chris Lumens <clumens@redhat.com>
-#
-
-class PartSpec(object):
-    def __init__(self, mountpoint=None, fstype=None, size=None, maxSize=None,
-                 grow=False, btr=False, lv=False, singlePV=False, weight=0,
-                 requiredSpace=0, encrypted=False):
-        """ Create a new storage specification.  These are used to specify
-            the default partitioning layout as an object before we have the
-            storage system up and running.  The attributes are obvious
-            except for the following:
-
-            btr -- Should this be allocated as a btrfs subvolume?  If not,
-                   it will be allocated as a partition.
-            lv -- Should this be allocated as a logical volume?  If not,
-                  it will be allocated as a partition.
-            singlePV -- Should this logical volume map to a single physical
-                        volume in the volume group?  Implies lv=True
-            weight -- An integer that modifies the sort algorithm for partition
-                      requests.  A larger value means the partition will end up
-                      closer to the front of the disk.  This is mainly used to
-                      make sure /boot ends up in front, and any special (PReP,
-                      appleboot, etc.) partitions end up in front of /boot.
-                      This value means nothing unless lv and btr are both False.
-            requiredSpace -- This value is only taken into account if
-                             lv=True, and specifies the size in MB that the
-                             containing VG must be for this PartSpec to even
-                             get used.  The VG's size is calculated before any
-                             other LVs are created inside it.  If not enough
-                             space exists, this PartSpec will never get turned
-                             into an LV.
-            encrypted -- Should this request be encrypted? For logical volume
-                         requests, this is satisfied if the PVs are encrypted
-                         as in the case of encrypted LVM autopart.
-        """
-
-        self.mountpoint = mountpoint
-        self.fstype = fstype
-        self.size = size
-        self.maxSize = maxSize
-        self.grow = grow
-        self.lv = lv
-        self.btr = btr
-        self.singlePV = singlePV
-        self.weight = weight
-        self.requiredSpace = requiredSpace
-        self.encrypted = encrypted
-
-        if self.singlePV and not self.lv:
-            self.lv = True
-
-    def __str__(self):
-        s = ("%(type)s instance (%(id)s) -- \n"
-             "  mountpoint = %(mountpoint)s  lv = %(lv)s  singlePV = %(singlePV)s"
-             "  btrfs = %(btrfs)s\n"
-             "  weight = %(weight)s  fstype = %(fstype)s  encrypted = %(enc)s\n"
-             "  size = %(size)s  maxSize = %(maxSize)s  grow = %(grow)s\n" %
-             {"type": self.__class__.__name__, "id": "%#x" % id(self),
-              "mountpoint": self.mountpoint, "lv": self.lv, "btrfs": self.btr,
-              "singlePV": self.singlePV, "weight": self.weight,
-              "fstype": self.fstype, "size": self.size, "enc": self.encrypted,
-              "maxSize": self.maxSize, "grow": self.grow})
-
-        return s
diff --git a/pyanaconda/storage/platform.py b/pyanaconda/storage/platform.py
deleted file mode 100644
index 5221a30..0000000
--- a/pyanaconda/storage/platform.py
+++ /dev/null
@@ -1,409 +0,0 @@
-#
-# platform.py:  Architecture-specific information
-#
-# Copyright (C) 2009-2011
-# Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Authors: Chris Lumens <clumens@redhat.com>
-#
-import os
-import logging
-log = logging.getLogger("storage")
-
-import parted
-
-from . import arch
-from .flags import flags
-from .partspec import PartSpec
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-N_ = lambda x: x
-
-class Platform(object):
-    """Platform
-
-       A class containing platform-specific information and methods for use
-       during installation.  The intent is to eventually encapsulate all the
-       architecture quirks in one place to avoid lots of platform checks
-       throughout anaconda."""
-    _minimumSector = 0
-    _packages = []
-
-    # requirements for bootloader stage1 devices
-    _boot_stage1_device_types = []
-    _boot_stage1_format_types = []
-    _boot_stage1_mountpoints = []
-    _boot_stage1_max_end_mb = None
-    _boot_stage1_raid_levels = []
-    _boot_stage1_raid_metadata = []
-    _boot_stage1_raid_member_types = []
-    _boot_stage1_description = N_("bootloader device")
-    _boot_raid_description = N_("RAID Device")
-    _boot_partition_description = N_("First sector of boot partition")
-    _boot_descriptions = {}
-
-    _disklabel_types = []
-    _non_linux_format_types = []
-
-    def __init__(self):
-        """Creates a new Platform object.  This is basically an abstract class.
-           You should instead use one of the platform-specific classes as
-           returned by getPlatform below.  Not all subclasses need to provide
-           all the methods in this class."""
-
-        if flags.gpt and "gpt" in self._disklabel_types:
-            # move GPT to the top of the list
-            self._disklabel_types.remove("gpt")
-            self._disklabel_types.insert(0, "gpt")
-
-    def __call__(self):
-        return self
-
-    @property
-    def diskLabelTypes(self):
-        """A list of valid disklabel types for this architecture."""
-        return self._disklabel_types
-
-    @property
-    def defaultDiskLabelType(self):
-        """The default disklabel type for this architecture."""
-        return self.diskLabelTypes[0]
-
-    @property
-    def bootStage1ConstraintDict(self):
-        d = {"device_types": self._boot_stage1_device_types,
-             "format_types": self._boot_stage1_format_types,
-             "mountpoints": self._boot_stage1_mountpoints,
-             "max_end_mb": self._boot_stage1_max_end_mb,
-             "raid_levels": self._boot_stage1_raid_levels,
-             "raid_metadata": self._boot_stage1_raid_metadata,
-             "raid_member_types": self._boot_stage1_raid_member_types,
-             "descriptions": self._boot_descriptions}
-        return d
-
-    def requiredDiskLabelType(self, device_type):
-        return None
-
-    def bestDiskLabelType(self, device):
-        """The best disklabel type for the specified device."""
-        if flags.testing:
-            return self.defaultDiskLabelType
-
-        # if there's a required type for this device type, use that
-        labelType = self.requiredDiskLabelType(device.partedDevice.type)
-        log.debug("required disklabel type for %s (%s) is %s"
-                  % (device.name, device.partedDevice.type, labelType))
-        if not labelType:
-            # otherwise, use the first supported type for this platform
-            # that is large enough to address the whole device
-            labelType = self.defaultDiskLabelType
-            log.debug("default disklabel type for %s is %s" % (device.name,
-                                                               labelType))
-            for lt in self.diskLabelTypes:
-                l = parted.freshDisk(device=device.partedDevice, ty=lt)
-                if l.maxPartitionStartSector > device.partedDevice.length:
-                    labelType = lt
-                    log.debug("selecting %s disklabel for %s based on size"
-                              % (labelType, device.name))
-                    break
-
-        return labelType
-
-    @property
-    def minimumSector(self, disk):
-        """Return the minimum starting sector for the provided disk."""
-        return self._minimumSector
-
-    @property
-    def packages (self):
-        _packages = self._packages
-        if flags.boot_cmdline.get('fips', None) == '1':
-            _packages.append('dracut-fips')
-        return _packages
-
-    def setDefaultPartitioning(self):
-        """Return the default platform-specific partitioning information."""
-        return [PartSpec(mountpoint="/boot",
-                         size=500, weight=self.weight(mountpoint="/boot"))]
-
-    def weight(self, fstype=None, mountpoint=None):
-        """ Given an fstype (as a string) or a mountpoint, return an integer
-            for the base sorting weight.  This is used to modify the sort
-            algorithm for partition requests, mainly to make sure bootable
-            partitions and /boot are placed where they need to be."""
-        if mountpoint == "/boot":
-            return 2000
-        else:
-            return 0
-
-class X86(Platform):
-    _boot_stage1_device_types = ["disk"]
-    _boot_mbr_description = N_("Master Boot Record")
-    _boot_descriptions = {"disk": _boot_mbr_description,
-                          "partition": Platform._boot_partition_description,
-                          "mdarray": Platform._boot_raid_description}
-
-
-    _disklabel_types = ["msdos", "gpt"]
-    # XXX hpfs, if reported by blkid/udev, will end up with a type of None
-    _non_linux_format_types = ["vfat", "ntfs", "hpfs"]
-
-    def __init__(self):
-        super(X86, self).__init__()
-
-    def setDefaultPartitioning(self):
-        """Return the default platform-specific partitioning information."""
-        ret = Platform.setDefaultPartitioning(self)
-        ret.append(PartSpec(fstype="biosboot", size=1,
-                            weight=self.weight(fstype="biosboot")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        score = Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
-        if score:
-            return score
-        elif fstype == "biosboot":
-            return 5000
-        else:
-            return 0
-
-class EFI(Platform):
-
-    _boot_stage1_format_types = ["efi"]
-    _boot_stage1_device_types = ["partition"]
-    _boot_stage1_mountpoints = ["/boot/efi"]
-    _boot_efi_description = N_("EFI System Partition")
-    _boot_descriptions = {"partition": _boot_efi_description,
-                          "mdarray": Platform._boot_raid_description}
-
-    _disklabel_types = ["gpt"]
-    # XXX hpfs, if reported by blkid/udev, will end up with a type of None
-    _non_linux_format_types = ["vfat", "ntfs", "hpfs"]
-
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
-        ret.append(PartSpec(mountpoint="/boot/efi", fstype="efi", size=20,
-                            maxSize=200,
-                            grow=True, weight=self.weight(fstype="efi")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        score = Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
-        if score:
-            return score
-        elif fstype == "efi" or mountpoint == "/boot/efi":
-            return 5000
-        else:
-            return 0
-
-class MacEFI(EFI):
-    _boot_stage1_format_types = ["hfs+"]
-    _boot_efi_description = N_("Apple EFI Boot Partition")
-    _non_linux_format_types = ["hfs+"]
-    _packages = ["mactel-boot"]
-
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
-        ret.append(PartSpec(mountpoint="/boot/efi", fstype="hfs+", size=20,
-                            maxSize=200,
-                            grow=True, weight=self.weight(mountpoint="/boot/efi")))
-        return ret
-
-class PPC(Platform):
-    _ppcMachine = arch.getPPCMachine()
-    _boot_stage1_device_types = ["partition"]
-
-    @property
-    def ppcMachine(self):
-        return self._ppcMachine
-
-class IPSeriesPPC(PPC):
-    _boot_stage1_format_types = ["prepboot"]
-    _boot_stage1_max_end_mb = 10
-    _boot_prep_description = N_("PReP Boot Partition")
-    _boot_descriptions = {"partition": _boot_prep_description}
-    _disklabel_types = ["msdos"]
-
-    def setDefaultPartitioning(self):
-        ret = PPC.setDefaultPartitioning(self)
-        ret.append(PartSpec(fstype="prepboot", size=4,
-                            weight=self.weight(fstype="prepboot")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        score = Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
-        if score:
-            return score
-        elif fstype == "prepboot":
-            return 5000
-        else:
-            return 0
-
-class NewWorldPPC(PPC):
-    _boot_stage1_format_types = ["appleboot"]
-    _boot_apple_description = N_("Apple Bootstrap Partition")
-    _boot_descriptions = {"partition": _boot_apple_description}
-    _disklabel_types = ["mac"]
-    _non_linux_format_types = ["hfs", "hfs+"]
-
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
-        ret.append(PartSpec(fstype="appleboot", size=1, maxSize=1,
-                            weight=self.weight(fstype="appleboot")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        score = Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
-        if score:
-            return score
-        elif fstype == "appleboot":
-            return 5000
-        else:
-            return 0
-
-class PS3(PPC):
-    pass
-
-class S390(Platform):
-    _packages = ["s390utils"]
-    _disklabel_types = ["msdos", "dasd"]
-    _boot_stage1_device_types = ["disk", "partition"]
-    _boot_dasd_description = N_("DASD")
-    _boot_zfcp_description = N_("zFCP")
-    _boot_descriptions = {"dasd": _boot_dasd_description,
-                          "zfcp": _boot_zfcp_description,
-                          "partition": Platform._boot_partition_description}
-
-    def __init__(self):
-        Platform.__init__(self)
-
-    def setDefaultPartitioning(self):
-        """Return the default platform-specific partitioning information."""
-        return [PartSpec(mountpoint="/boot", size=500,
-                         weight=self.weight(mountpoint="/boot"), lv=True,
-                         singlePV=True)]
-
-    def requiredDiskLabelType(self, device_type):
-        """The required disklabel type for the specified device type."""
-        if device_type == parted.DEVICE_DASD:
-            return "dasd"
-
-        return super(S390, self).requiredDiskLabelType(device_type)
-
-class Sparc(Platform):
-    _boot_stage1_format_types = []
-    _boot_stage1_mountpoints = []
-    _boot_stage1_max_end_mb = None
-    _disklabel_types = ["sun"]
-
-    @property
-    def minimumSector(self, disk):
-        (cylinders, heads, sectors) = disk.device.biosGeometry
-        start = long(sectors * heads)
-        start /= long(1024 / disk.device.sectorSize)
-        return start+1
-
-class ARM(Platform):
-    _armMachine = None
-    _boot_stage1_device_types = ["disk"]
-    _boot_mbr_description = N_("Master Boot Record")
-    _boot_descriptions = {"disk": _boot_mbr_description,
-                          "partition": Platform._boot_partition_description}
-
-    _disklabel_types = ["msdos"]
-
-    @property
-    def armMachine(self):
-        if not self._armMachine:
-            self._armMachine = arch.getARMMachine()
-        return self._armMachine
-
-    def weight(self, fstype=None, mountpoint=None):
-        """Return the ARM platform-specific weight for the / partition.
-           On ARM images '/' must be the last partition, so we try to
-           weight it accordingly."""
-        if mountpoint == "/":
-            return -100
-        else:
-            return Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
-
-class omapARM(ARM):
-    _boot_stage1_format_types = ["vfat"]
-    _boot_stage1_device_types = ["partition"]
-    _boot_stage1_mountpoints = ["/boot/uboot"]
-    _boot_uboot_description = N_("U-Boot Partition")
-    _boot_descriptions = {"partition": _boot_uboot_description}
-
-    def setDefaultPartitioning(self):
-        """Return the ARM-OMAP platform-specific partitioning information."""
-        ret = [PartSpec(mountpoint="/boot/uboot", fstype="vfat",
-                        size=20, maxSize=200, grow=True,
-                        weight=self.weight(fstype="vfat", mountpoint="/boot/uboot"))]
-        ret.append(PartSpec(mountpoint="/", fstype="ext4",
-                            size=2000, maxSize=3000,
-                            weight=self.weight(mountpoint="/")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        """Return the ARM-OMAP platform-specific weights for the uboot
-           and / partitions.  On OMAP, uboot must be the first partition,
-           and '/' must be the last partition, so we try to weight them
-           accordingly."""
-        if fstype == "vfat" and mountpoint == "/boot/uboot":
-            return 6000
-        elif mountpoint == "/":
-            return -100
-        else:
-            return Platform.weight(self, fstype=fstype, mountpoint=mountpoint)
-
-def getPlatform():
-    """Check the architecture of the system and return an instance of a
-       Platform subclass to match.  If the architecture could not be determined,
-       raise an exception."""
-    if arch.isPPC():
-        ppcMachine = arch.getPPCMachine()
-
-        if (ppcMachine == "PMac" and arch.getPPCMacGen() == "NewWorld"):
-            return NewWorldPPC()
-        elif ppcMachine in ["iSeries", "pSeries"]:
-            return IPSeriesPPC()
-        elif ppcMachine == "PS3":
-            return PS3()
-        else:
-            raise SystemError, "Unsupported PPC machine type: %s" % ppcMachine
-    elif arch.isS390():
-        return S390()
-    elif arch.isSparc():
-        return Sparc()
-    elif arch.isEfi():
-        if arch.isMactel():
-            return MacEFI()
-        else:
-            return EFI()
-    elif arch.isX86():
-        return X86()
-    elif arch.isARM():
-        armMachine = arch.getARMMachine()
-        if armMachine == "omap":
-            return omapARM()
-        else:
-            return ARM()
-    else:
-        raise SystemError, "Could not determine system architecture."
-
-global platform
-platform = getPlatform()
diff --git a/pyanaconda/storage/pyudev.py b/pyanaconda/storage/pyudev.py
deleted file mode 100644
index 705b93d..0000000
--- a/pyanaconda/storage/pyudev.py
+++ /dev/null
@@ -1,232 +0,0 @@
-from __future__ import print_function
-
-import sys
-import os
-import fnmatch
-from ctypes import *
-
-
-# XXX this one may need some tweaking...
-def find_library(name, somajor=0):
-    env = os.environ.get("LD_LIBRARY_PATH")
-    common = ["/lib64", "/lib"]
-
-    if env:
-        libdirs = env.split(":") + common
-    else:
-        libdirs = common
-
-    libdirs = filter(os.path.isdir, libdirs)
-
-    for dir in libdirs:
-        files = fnmatch.filter(os.listdir(dir), "lib%s.so.%d" % (name, somajor))
-        files = [os.path.join(dir, file) for file in files]
-
-        if files:
-            break
-
-    if files:
-        return files[0]
-    else:
-        return None
-
-# find the udev library
-name = "udev"
-somajor = 1
-libudev = find_library(name=name, somajor=somajor)
-
-if not libudev or not os.path.exists(libudev):
-    raise ImportError, "No library named %s.%d" % (name, somajor)
-
-# load the udev library
-libudev = CDLL(libudev)
-
-
-# create aliases for needed functions and set the return types where needed
-libudev_udev_new = libudev.udev_new
-libudev_udev_new.argtypes = []
-libudev_udev_new.restype = c_void_p
-libudev_udev_unref = libudev.udev_unref
-libudev_udev_unref.argtypes = [ c_void_p ]
-
-libudev_udev_device_new_from_syspath = libudev.udev_device_new_from_syspath
-libudev_udev_device_new_from_syspath.restype = c_void_p
-libudev_udev_device_new_from_syspath.argtypes = [ c_void_p, c_char_p ]
-libudev_udev_device_unref = libudev.udev_device_unref
-libudev_udev_device_unref.argtypes = [ c_void_p ]
-
-libudev_udev_device_get_syspath = libudev.udev_device_get_syspath
-libudev_udev_device_get_syspath.restype = c_char_p
-libudev_udev_device_get_syspath.argtypes = [ c_void_p ]
-libudev_udev_device_get_sysname = libudev.udev_device_get_sysname
-libudev_udev_device_get_sysname.restype = c_char_p
-libudev_udev_device_get_sysname.argtypes = [ c_void_p ]
-libudev_udev_device_get_devpath = libudev.udev_device_get_devpath
-libudev_udev_device_get_devpath.restype = c_char_p
-libudev_udev_device_get_devpath.argtypes = [ c_void_p ]
-libudev_udev_device_get_devtype = libudev.udev_device_get_devtype
-libudev_udev_device_get_devtype.restype = c_char_p
-libudev_udev_device_get_devtype.argtypes = [ c_void_p ]
-libudev_udev_device_get_devnode = libudev.udev_device_get_devnode
-libudev_udev_device_get_devnode.restype = c_char_p
-libudev_udev_device_get_devnode.argtypes = [ c_void_p ]
-libudev_udev_device_get_subsystem = libudev.udev_device_get_subsystem
-libudev_udev_device_get_subsystem.restype = c_char_p
-libudev_udev_device_get_subsystem.argtypes = [ c_void_p ]
-libudev_udev_device_get_sysnum = libudev.udev_device_get_sysnum
-libudev_udev_device_get_sysnum.restype = c_char_p
-libudev_udev_device_get_sysnum.argtypes = [ c_void_p ]
-
-libudev_udev_device_get_properties_list_entry = libudev.udev_device_get_properties_list_entry
-libudev_udev_device_get_properties_list_entry.restype = c_void_p
-libudev_udev_device_get_properties_list_entry.argtypes = [ c_void_p ]
-libudev_udev_list_entry_get_next = libudev.udev_list_entry_get_next
-libudev_udev_list_entry_get_next.restype = c_void_p
-libudev_udev_list_entry_get_next.argtypes = [ c_void_p ]
-
-libudev_udev_list_entry_get_name = libudev.udev_list_entry_get_name
-libudev_udev_list_entry_get_name.restype = c_char_p
-libudev_udev_list_entry_get_name.argtypes = [ c_void_p ]
-libudev_udev_list_entry_get_value = libudev.udev_list_entry_get_value
-libudev_udev_list_entry_get_value.restype = c_char_p
-libudev_udev_list_entry_get_value.argtypes = [ c_void_p ]
-
-libudev_udev_enumerate_new = libudev.udev_enumerate_new
-libudev_udev_enumerate_new.restype = c_void_p
-libudev_udev_enumerate_new.argtypes = [ c_void_p ]
-libudev_udev_enumerate_unref = libudev.udev_enumerate_unref
-libudev_udev_enumerate_unref.argtypes = [ c_void_p ]
-
-libudev_udev_enumerate_add_match_subsystem = libudev.udev_enumerate_add_match_subsystem
-libudev_udev_enumerate_add_match_subsystem.restype = c_int
-libudev_udev_enumerate_add_match_subsystem.argtypes = [ c_void_p, c_char_p ]
-libudev_udev_enumerate_scan_devices = libudev.udev_enumerate_scan_devices
-libudev_udev_enumerate_scan_devices.restype = c_int
-libudev_udev_enumerate_scan_devices.argtypes = [ c_void_p ]
-libudev_udev_enumerate_get_list_entry = libudev.udev_enumerate_get_list_entry
-libudev_udev_enumerate_get_list_entry.restype = c_void_p
-libudev_udev_enumerate_get_list_entry.argtypes = [ c_void_p ]
-
-libudev_udev_device_get_devlinks_list_entry = libudev.udev_device_get_devlinks_list_entry
-libudev_udev_device_get_devlinks_list_entry.restype = c_void_p
-libudev_udev_device_get_devlinks_list_entry.argtypes = [ c_void_p ]
-
-
-class UdevDevice(dict):
-
-    def __init__(self, udev, sysfs_path):
-        dict.__init__(self)
-
-        # create new udev device from syspath
-        udev_device = libudev_udev_device_new_from_syspath(udev, sysfs_path)
-        if not udev_device:
-            # device does not exist
-            return
-
-        # set syspath and sysname properties
-        self.syspath = libudev_udev_device_get_syspath(udev_device)
-        self.sysname = libudev_udev_device_get_sysname(udev_device)
-
-        # get the devlinks list
-        devlinks = []
-        devlinks_entry = libudev_udev_device_get_devlinks_list_entry(udev_device)
-
-        while devlinks_entry:
-            path = libudev_udev_list_entry_get_name(devlinks_entry)
-            devlinks.append(path)
-
-            devlinks_entry = libudev_udev_list_entry_get_next(devlinks_entry)
-
-        # add devlinks list to the dictionary
-        self["symlinks"] = devlinks
-
-        # get the first property entry
-        property_entry = libudev_udev_device_get_properties_list_entry(udev_device)
-
-        while property_entry:
-            name = libudev_udev_list_entry_get_name(property_entry)
-            value = libudev_udev_list_entry_get_value(property_entry)
-
-            # lvm outputs values for multiple lvs in one line
-            # we want to split them and make a list
-            # if the first lv's value is empty we end up with a value starting
-            # with name=, prepend a space that our split does the right thing
-            if value.startswith("%s=" % name):
-                value = " " + value
-
-            if value.count(" %s=" % name):
-                value = value.split(" %s=" % name)
-
-            self[name] = value
-
-            # get next property entry
-            property_entry = libudev_udev_list_entry_get_next(property_entry)
-
-        # set additional properties
-        self.devpath = libudev_udev_device_get_devpath(udev_device)
-        self.subsystem = libudev_udev_device_get_subsystem(udev_device)
-        self.devtype = libudev_udev_device_get_devtype(udev_device)
-        self.sysnum = libudev_udev_device_get_sysnum(udev_device)
-        self.devnode = libudev_udev_device_get_devnode(udev_device)
-
-        # cleanup
-        libudev_udev_device_unref(udev_device)
-
-
-class Udev(object):
-
-    def __init__(self):
-        self.udev = libudev_udev_new()
-
-    def create_device(self, sysfs_path):
-        return UdevDevice(self.udev, sysfs_path)
-
-    def enumerate_devices(self, subsystem=None):
-        enumerate = libudev_udev_enumerate_new(self.udev)
-
-        # add the match subsystem
-        if subsystem is not None:
-            rc = libudev_udev_enumerate_add_match_subsystem(enumerate, subsystem)
-            if not rc == 0:
-                print("error: unable to add the match subsystem", file=sys.stderr)
-                libudev_udev_enumerate_unref(enumerate)
-                return []
-
-        # scan the devices
-        rc = libudev_udev_enumerate_scan_devices(enumerate)
-        if not rc == 0:
-            print("error: unable to enumerate the devices", file=sys.stderr)
-            libudev_udev_enumerate_unref(enumerate)
-            return []
-
-        # create the list of sysfs paths
-        sysfs_paths = []
-
-        # get the first list entry
-        list_entry = libudev_udev_enumerate_get_list_entry(enumerate)
-
-        while list_entry:
-            sysfs_path = libudev_udev_list_entry_get_name(list_entry)
-            sysfs_paths.append(sysfs_path)
-
-            # get next list entry
-            list_entry = libudev_udev_list_entry_get_next(list_entry)
-
-        # cleanup
-        libudev_udev_enumerate_unref(enumerate)
-
-        return sysfs_paths
-
-    def scan_devices(self, sysfs_paths=None):
-        if sysfs_paths is None:
-            sysfs_paths = self.enumerate_devices()
-
-        for sysfs_path in sysfs_paths:
-            device = self.create_device(sysfs_path)
-
-            if device:
-                yield device
-
-    def unref(self):
-        libudev_udev_unref(self.udev)
-        self.udev = None
diff --git a/pyanaconda/storage/size.py b/pyanaconda/storage/size.py
deleted file mode 100644
index 0081d52..0000000
--- a/pyanaconda/storage/size.py
+++ /dev/null
@@ -1,235 +0,0 @@
-# size.py
-# Python module to represent storage sizes
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): David Cantrell <dcantrell@redhat.com>
-
-import re
-
-from decimal import Decimal
-from decimal import InvalidOperation
-
-from errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-# Decimal prefixes for different size increments, along with the name
-# and accepted abbreviation for the prefix.  These prefixes are all
-# for 'bytes'.
-_decimalPrefix = [(1000, _("kilo"), _("k")),
-                  (1000**2, _("mega"), _("M")),
-                  (1000**3, _("giga"), _("G")),
-                  (1000**4, _("tera"), _("T")),
-                  (1000**5, _("peta"), _("P")),
-                  (1000**6, _("exa"), _("E")),
-                  (1000**7, _("zetta"), _("Z")),
-                  (1000**8, _("yotta"), _("Y"))]
-
-# Binary prefixes for the different size increments.  Same structure
-# as the above list.
-_binaryPrefix = [(1024, _("kibi"), _("Ki")),
-                 (1024**2, _("mebi"), _("Mi")),
-                 (1024**3, _("gibi"), _("Gi")),
-                 (1024**4, _("tebi"), None),
-                 (1024**5, _("pebi"), None),
-                 (1024**6, _("ebi"), None),
-                 (1024**7, _("zebi"), None),
-                 (1024**8, _("yobi"), None)]
-
-_bytes = [_('b'), _('byte'), _('bytes')]
-_prefixes = _decimalPrefix + _binaryPrefix
-
-def _makeSpecs(prefix, abbr):
-    """ Internal method used to generate a list of specifiers. """
-    specs = []
-
-    if prefix:
-        specs.append(prefix.lower() + _("byte"))
-        specs.append(prefix.lower() + _("bytes"))
-
-    if abbr:
-        specs.append(abbr.lower() + _("b"))
-
-    return specs
-
-def _parseSpec(spec):
-    """ Parse string representation of size. """
-    if not spec:
-        raise ValueError("invalid size specification", spec)
-
-    m = re.match(r'([0-9.]+)\s*([A-Za-z]*)$', spec.strip())
-    if not m:
-        raise ValueError("invalid size specification", spec)
-
-    try:
-        size = Decimal(m.groups()[0])
-    except InvalidOperation:
-        raise ValueError("invalid size specification", spec)
-
-    if size < 0:
-        raise SizeNotPositiveError("spec= param must be >=0")
-
-    specifier = m.groups()[1].lower()
-    if specifier in _bytes or not specifier:
-        return size
-
-    for factor, prefix, abbr in _prefixes:
-        check = _makeSpecs(prefix, abbr)
-
-        if specifier in check:
-            return size * factor
-
-    raise ValueError("invalid size specification", spec)
-
-class Size(Decimal):
-    """ Common class to represent storage device and filesystem sizes.
-        Can handle parsing strings such as 45MB or 6.7GB to initialize
-        itself, or can be initialized with a numerical size in bytes.
-        Also generates human readable strings to a specified number of
-        decimal places.
-    """
-
-    def __new__(cls, bytes=None,  spec=None):
-        """ Initialize a new Size object.  Must pass either bytes or spec,
-            but not both.  The bytes parameter is a numerical value for
-            the size this object represents, in bytes.  The spec parameter
-            is a string specification of the size using any of the size
-            specifiers in the _decimalPrefix or _binaryPrefix lists combined
-            with a 'b' or 'B'.  For example, to specify 640 kilobytes, you
-            could pass any of these parameter:
-
-                spec="640kb"
-                spec="640 kb"
-                spec="640KB"
-                spec="640 KB"
-                spec="640 kilobytes"
-
-            If you want to use spec to pass a bytes value, you can use the
-            letter 'b' or 'B' or simply leave the specifier off and bytes
-            will be assumed.
-        """
-        if bytes and spec:
-            raise SizeParamsError("only specify one parameter")
-
-        if bytes is not None:
-            if type(bytes).__name__ in ["int", "long", "float", 'Decimal'] and bytes >= 0:
-                self = Decimal.__new__(cls, value=bytes)
-            else:
-                raise SizeNotPositiveError("bytes= param must be >=0")
-        elif spec:
-            self = Decimal.__new__(cls, value=_parseSpec(spec))
-        else:
-            raise SizeParamsError("missing bytes= or spec=")
-
-        return self
-
-    def __str__(self, context=None):
-        return self.humanReadable()
-
-    def __repr__(self):
-        return "Size('%s')" % self
-
-    def __add__(self, other, context=None):
-        return Size(bytes=Decimal.__add__(self, other, context=context))
-
-    # needed to make sum() work with Size arguments
-    def __radd__(self, other, context=None):
-        return Size(bytes=Decimal.__radd__(self, other, context=context))
-
-    def __sub__(self, other, context=None):
-        # subtraction is implemented using __add__ and negation, so we'll
-        # be getting passed a Size
-        return Decimal.__sub__(self, other, context=context)
-
-    def __mul__(self, other, context=None):
-        return Size(bytes=Decimal.__mul__(self, other, context=context))
-
-    def __div__(self, other, context=None):
-        return Size(bytes=Decimal.__div__(self, other, context=context))
-
-    def _trimEnd(self, val):
-        """ Internal method to trim trailing zeros. """
-        val = re.sub(r'(\.\d*?)0+$', '\\1', val)
-        while val.endswith('.'):
-            val = val[:-1]
-
-        return val
-
-    def convertTo(self, spec="b"):
-        """ Return the size in the units indicated by the specifier.  The
-            specifier can be prefixes from the _decimalPrefix and
-            _binaryPrefix lists combined with 'b' or 'B' for abbreviations)
-            or 'bytes' (for prefixes like kilo or mega).  The size is
-            returned as a Decimal.
-        """
-        spec = spec.lower()
-
-        if spec in _bytes:
-            return self
-
-        for factor, prefix, abbr in _prefixes:
-            check = _makeSpecs(prefix, abbr)
-
-            if spec in check:
-                return Decimal(self / Decimal(factor))
-
-        return None
-
-    def humanReadable(self, places=None, max_places=2):
-        """ Return a string representation of this size with appropriate
-            size specifier and in the specified number of decimal places
-            (default: auto with a maximum of 2 decimal places).
-        """
-        if places is not None and places < 0:
-            raise SizePlacesError("places= must be >=0 or None")
-
-        if max_places is not None and max_places < 0:
-            raise SizePlacesError("max_places= must be >=0 or None")
-
-        check = self._trimEnd("%d" % self)
-
-        if Decimal(check) < 1000:
-            return "%s B" % check
-
-        for factor, prefix, abbr in _prefixes:
-            newcheck = super(Size, self).__div__(Decimal(factor))
-
-            if newcheck < 1000:
-                # nice value, use this factor, prefix and abbr
-                break
-
-        if places is not None:
-            fmt = "%%.%df" % places
-            retval = fmt % newcheck
-        else:
-            retval = self._trimEnd("%f" % newcheck)
-
-        if max_places is not None:
-            (whole, point, fraction) = retval.partition(".")
-            if point and len(fraction) > max_places:
-                if max_places == 0:
-                    retval = whole
-                else:
-                    retval = "%s.%s" % (whole, fraction[:max_places])
-
-        if abbr:
-            return retval + " " + abbr + _("B")
-        else:
-            return retval + " " + prefix + P_("byte", "bytes", newcheck)
diff --git a/pyanaconda/storage/storage_log.py b/pyanaconda/storage/storage_log.py
deleted file mode 100644
index 62ad86f..0000000
--- a/pyanaconda/storage/storage_log.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import inspect
-import logging
-
-log = logging.getLogger("storage")
-log.addHandler(logging.NullHandler())
-
-def function_name_and_depth():
-    IGNORED_FUNCS = ["function_name_and_depth",
-                     "log_method_call",
-                     "log_method_return"]
-    stack = inspect.stack()
-
-    for i, frame in enumerate(stack):
-        methodname = frame[3]
-        if methodname not in IGNORED_FUNCS:
-            return (methodname, len(stack) - i)
-
-    return ("unknown function?", 0)
-
-def log_method_call(d, *args, **kwargs):
-    classname = d.__class__.__name__
-    (methodname, depth) = function_name_and_depth()
-    spaces = depth * ' '
-    fmt = "%s%s.%s:"
-    fmt_args = [spaces, classname, methodname]
-
-    for arg in args:
-        fmt += " %s ;"
-        fmt_args.append(arg)
-
-    for k, v in kwargs.items():
-        fmt += " %s: %s ;"
-        if "pass" in k.lower() and v:
-            v = "Skipped"
-        fmt_args.extend([k, v])
-
-    logging.getLogger("storage").debug(fmt % tuple(fmt_args))
-
-def log_method_return(d, retval):
-    classname = d.__class__.__name__
-    (methodname, depth) = function_name_and_depth()
-    spaces = depth * ' '
-    fmt = "%s%s.%s returned %s"
-    fmt_args = (spaces, classname, methodname, retval)
-    logging.getLogger("storage").debug(fmt % fmt_args)
-
diff --git a/pyanaconda/storage/tsort.py b/pyanaconda/storage/tsort.py
deleted file mode 100644
index 52a871f..0000000
--- a/pyanaconda/storage/tsort.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/python
-# tsort.py
-# Topological sorting.
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#
-
-class CyclicGraphError(Exception):
-    pass
-
-def tsort(graph):
-    order = []  # sorted list of items
-
-    if not graph or not graph['items']:
-        return order
-
-    # determine which nodes have no incoming edges
-    roots = [n for n in graph['items'] if graph['incoming'][n] == 0]
-    if not roots:
-        raise CyclicGraphError("no root nodes")
-
-    visited = []    # list of nodes visited, for cycle detection
-    while roots:
-        # remove a root, add it to the order
-        root = roots.pop()
-        if root in visited:
-            raise CyclicGraphError("graph contains cycles")
-
-        visited.append(root)
-        i = graph['items'].index(root)
-        order.append(root)
-        # remove each edge from the root to another node
-        for (parent, child) in [e for e in graph['edges'] if e[0] == root]:
-            graph['incoming'][child] -= 1
-            graph['edges'].remove((parent, child))
-            # if destination node is now a root, add it to roots
-            if graph['incoming'][child] == 0:
-                roots.append(child)
-
-    if len(graph['items']) != len(visited):
-        raise CyclicGraphError("graph contains cycles")
-
-
-    return order
-
-def create_graph(items, edges):
-    """ Create a graph based on a list of items and a list of edges.
-
-        Arguments:
-
-            items   -   an iterable containing (hashable) items to sort
-            edges   -   an iterable containing (parent, child) edge pair tuples
-
-        Return Value:
-
-            The return value is a dictionary representing the directed graph.
-            It has three keys:
-
-                items is the same as the input argument of the same name
-                edges is the same as the input argument of the same name
-                incoming is a dict of incoming edge count hashed by item
-
-    """
-    graph = {'items': [],       # the items to sort
-             'edges': [],       # partial order info: (parent, child) pairs
-             'incoming': {}}    # incoming edge count for each item
-
-    graph['items'] = items
-    graph['edges'] = edges
-    for item in items:
-        graph['incoming'][item] = 0
-
-    for (parent, child) in edges:
-        graph['incoming'][child] += 1
-
-    return graph 
-
-
-if __name__ == "__main__":
-
-    items = [5, 2, 3, 4, 1]
-    edges = [(1, 2), (2, 4), (4, 5), (3, 2)]
-
-    print items
-    print edges
-
-    graph = create_graph(items, edges)
-    print tsort(graph)
-
diff --git a/pyanaconda/storage/udev.py b/pyanaconda/storage/udev.py
deleted file mode 100644
index f8ba09c..0000000
--- a/pyanaconda/storage/udev.py
+++ /dev/null
@@ -1,737 +0,0 @@
-# udev.py
-# Python module for querying the udev database for device information.
-#
-# Copyright (C) 2009, 2013  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@redhat.com>
-#                    Chris Lumens <clumens@redhat.com>
-#
-
-import os
-import re
-
-import util
-from errors import *
-
-import pyudev
-global_udev = pyudev.Udev()
-
-import logging
-log = logging.getLogger("storage")
-
-def udev_enumerate_devices(deviceClass="block"):
-    devices = global_udev.enumerate_devices(subsystem=deviceClass)
-    return [path[4:] for path in devices]
-
-def udev_get_device(sysfs_path):
-    if not os.path.exists("/sys%s" % sysfs_path):
-        log.debug("%s does not exist" % sysfs_path)
-        return None
-
-    # XXX we remove the /sys part when enumerating devices,
-    # so we have to prepend it when creating the device
-    dev = global_udev.create_device("/sys" + sysfs_path)
-
-    if dev:
-        dev["name"] = dev.sysname
-        dev["sysfs_path"] = sysfs_path
-
-        # now add in the contents of the uevent file since they're handy
-        dev = udev_parse_uevent_file(dev)
-
-    return dev
-
-def udev_get_devices(deviceClass="block"):
-    udev_settle()
-    entries = []
-    for path in udev_enumerate_devices(deviceClass):
-        entry = udev_get_device(path)
-        if entry:
-            entries.append(entry)
-    return entries
-
-def udev_parse_uevent_file(dev):
-    path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path'])
-    if not os.access(path, os.R_OK):
-        return dev
-
-    with open(path) as f:
-        for line in f.readlines():
-            (key, equals, value) = line.strip().partition("=")
-            if not equals:
-                continue
-
-            dev[key] = value
-
-    return dev
-
-def udev_settle():
-    # wait maximal 300 seconds for udev to be done running blkid, lvm,
-    # mdadm etc. This large timeout is needed when running on machines with
-    # lots of disks, or with slow disks
-    util.run_program(["udevadm", "settle", "--timeout=300"])
-
-def udev_trigger(subsystem=None, action="add", name=None):
-    argv = ["trigger", "--action=%s" % action]
-    if subsystem:
-        argv.append("--subsystem-match=%s" % subsystem)
-    if name:
-        argv.append("--sysname-match=%s" % name)
-
-    util.run_program(["udevadm"] + argv)
-    udev_settle()
-
-def udev_resolve_devspec(devspec):
-    if not devspec:
-        return None
-
-    import devices as _devices
-    ret = None
-    for dev in udev_get_block_devices():
-        if devspec.startswith("LABEL="):
-            if udev_device_get_label(dev) == devspec[6:]:
-                ret = dev
-                break
-        elif devspec.startswith("UUID="):
-            if udev_device_get_uuid(dev) == devspec[5:]:
-                ret = dev
-                break
-        elif udev_device_get_name(dev) == _devices.devicePathToName(devspec):
-            ret = dev
-            break
-        else:
-            spec = devspec
-            if not spec.startswith("/dev/"):
-                spec = os.path.normpath("/dev/" + spec)
-
-            for link in dev["symlinks"]:
-                if spec == link:
-                    ret = dev
-                    break
-
-    del _devices
-    if ret:
-        return udev_device_get_name(ret)
-
-def udev_resolve_glob(glob):
-    import fnmatch
-    ret = []
-
-    if not glob:
-        return ret
-
-    for dev in udev_get_block_devices():
-        name = udev_device_get_name(dev)
-
-        if fnmatch.fnmatch(name, glob):
-            ret.append(name)
-        else:
-            for link in dev["symlinks"]:
-                if fnmatch.fnmatch(link, glob):
-                    ret.append(name)
-
-    return ret
-
-def udev_get_block_devices():
-    udev_settle()
-    entries = []
-    for path in udev_enumerate_block_devices():
-        entry = udev_get_block_device(path)
-        if entry:
-            if entry["name"].startswith("md"):
-                # mdraid is really braindead, when a device is stopped
-                # it is no longer usefull in anyway (and we should not
-                # probe it) yet it still sticks around, see bug rh523387
-                state = None
-                state_file = "/sys/%s/md/array_state" % entry["sysfs_path"]
-                if os.access(state_file, os.R_OK):
-                    state = open(state_file).read().strip()
-                if state == "clear":
-                    continue
-            entries.append(entry)
-    return entries
-
-def __is_blacklisted_blockdev(dev_name):
-    """Is this a blockdev we never want for an install?"""
-    if dev_name.startswith("ram") or dev_name.startswith("fd"):
-        return True
-
-    if os.path.exists("/sys/class/block/%s/device/model" %(dev_name,)):
-        model = open("/sys/class/block/%s/device/model" %(dev_name,)).read()
-        for bad in ("IBM *STMF KERNEL", "SCEI Flash-5", "DGC LUNZ"):
-            if model.find(bad) != -1:
-                log.info("ignoring %s with model %s" %(dev_name, model))
-                return True
-
-    return False
-
-def udev_enumerate_block_devices():
-    import os.path
-
-    return filter(lambda d: not __is_blacklisted_blockdev(os.path.basename(d)),
-                  udev_enumerate_devices(deviceClass="block"))
-
-def udev_get_block_device(sysfs_path):
-    dev = udev_get_device(sysfs_path)
-    if not dev or not dev.has_key("name"):
-        return None
-    else:
-        return dev
-
-
-# These are functions for retrieving specific pieces of information from
-# udev database entries.
-def udev_device_get_name(udev_info):
-    """ Return the best name for a device based on the udev db data. """
-    if "DM_NAME" in udev_info:
-        name = udev_info["DM_NAME"]
-    else:
-        name = udev_info["name"]
-
-    return name
-
-def udev_device_get_format(udev_info):
-    """ Return a device's format type as reported by udev. """
-    return udev_info.get("ID_FS_TYPE")
-
-def udev_device_get_uuid(udev_info):
-    """ Get the UUID from the device's format as reported by udev. """
-    md_uuid = udev_info.get("MD_UUID", '')
-    uuid = udev_info.get("ID_FS_UUID", '')
-    # we don't want to return the array's uuid as a member's uuid
-    if len(uuid) > 0 and \
-            re.sub(r'\W', '', md_uuid) != re.sub(r'\W', '', uuid):
-        return udev_info.get("ID_FS_UUID")
-
-def udev_device_get_label(udev_info):
-    """ Get the label from the device's format as reported by udev. """
-    return udev_info.get("ID_FS_LABEL")
-
-def udev_device_is_dm(info):
-    """ Return True if the device is a device-mapper device. """
-    return info.has_key("DM_NAME")
-
-def udev_device_is_md(info):
-    """ Return True if the device is a mdraid array device. """
-    # Don't identify partitions on mdraid arrays as raid arrays
-    if udev_device_is_partition(info):
-        return False
-
-    # The udev information keeps shifting around. Only md arrays have a
-    # /sys/class/block/<name>/md/ subdirectory.
-    md_dir = "/sys" + udev_device_get_sysfs_path(info) + "/md"
-    return os.path.exists(md_dir)
-
-def udev_device_is_cciss(info):
-    """ Return True if the device is a CCISS device. """
-    return udev_device_get_name(info).startswith("cciss")
-
-def udev_device_is_dasd(info):
-    """ Return True if the device is a dasd device. """
-    devname = info.get("DEVNAME")
-    if devname:
-        return devname.startswith("dasd")
-    else:
-        return False
-
-def udev_device_is_zfcp(info):
-    """ Return True if the device is a zfcp device. """
-    if info.get("DEVTYPE") != "disk":
-        return False
-
-    subsystem = "/sys" + info.get("sysfs_path")
-
-    while True:
-        topdir = os.path.realpath(os.path.dirname(subsystem))
-        driver = "%s/driver" % (topdir,)
-
-        if os.path.islink(driver):
-            subsystemname = os.path.basename(os.readlink(subsystem))
-            drivername = os.path.basename(os.readlink(driver))
-
-            if subsystemname == 'ccw' and drivername == 'zfcp':
-                return True
-
-        newsubsystem = os.path.dirname(topdir)
-
-        if newsubsystem == topdir:
-            break
-
-        subsystem = newsubsystem + "/subsystem"
-
-    return False
-
-def udev_device_get_zfcp_attribute(info, attr=None):
-    """ Return the value of the specified attribute of the zfcp device. """
-    if not attr:
-        log.debug("udev_device_get_zfcp_attribute() called with attr=None")
-        return None
-
-    attribute = "/sys%s/device/%s" % (info.get("sysfs_path"), attr,)
-    attribute = os.path.realpath(attribute)
-
-    if not os.path.isfile(attribute):
-        log.warning("%s is not a valid zfcp attribute" % (attribute,))
-        return None
-
-    return open(attribute, "r").read().strip()
-
-def udev_device_get_dasd_bus_id(info):
-    """ Return the CCW bus ID of the dasd device. """
-    return info.get("sysfs_path").split("/")[-3]
-
-def udev_device_get_dasd_flag(info, flag=None):
-    """ Return the specified flag for the dasd device. """
-    if flag is None:
-        return None
-
-    path = "/sys" + info.get("sysfs_path") + "/device/" + flag
-    if not os.path.isfile(path):
-        return None
-
-    return open(path, 'r').read().strip()
-
-def udev_device_is_cdrom(info):
-    """ Return True if the device is an optical drive. """
-    # FIXME: how can we differentiate USB drives from CD-ROM drives?
-    #         -- USB drives also generate a sdX device.
-    return info.get("ID_CDROM") == "1"
-
-def udev_device_is_disk(info):
-    """ Return True is the device is a disk. """
-    if udev_device_is_cdrom(info):
-        return False
-    has_range = os.path.exists("/sys/%s/range" % info['sysfs_path'])
-    return info.get("DEVTYPE") == "disk" or has_range
-
-def udev_device_is_partition(info):
-    has_start = os.path.exists("/sys/%s/start" % info['sysfs_path'])
-    return info.get("DEVTYPE") == "partition" or has_start
-
-def udev_device_is_loop(info):
-    """ Return True if the device is a configured loop device. """
-    return (udev_device_get_name(info).startswith("loop") and
-            os.path.isdir("/sys/%s/loop" % info['sysfs_path']))
-
-def udev_device_get_serial(udev_info):
-    """ Get the serial number/UUID from the device as reported by udev. """
-    return udev_info.get("ID_SERIAL_RAW", udev_info.get("ID_SERIAL_SHORT", udev_info.get("ID_SERIAL")))
-
-def udev_device_get_wwid(udev_info):
-    """ The WWID of a device is typically just its serial number, but with
-        colons in the name to make it more readable. """
-    serial = udev_device_get_serial(udev_info)
-    return util.insert_colons(serial) if serial else ""
-
-def udev_device_get_vendor(udev_info):
-    """ Get the vendor of the device as reported by udev. """
-    return udev_info.get("ID_VENDOR_FROM_DATABASE", udev_info.get("ID_VENDOR"))
-
-def udev_device_get_model(udev_info):
-    """ Get the model of the device as reported by udev. """
-    return udev_info.get("ID_MODEL_FROM_DATABASE", udev_info.get("ID_MODEL"))
-
-def udev_device_get_bus(udev_info):
-    """ Get the bus a device is connected to the system by. """
-    return udev_info.get("ID_BUS", "").upper()
-
-def udev_device_get_path(info):
-    return info["ID_PATH"]
-
-def udev_device_get_by_path(info):
-    if info.has_key('symlinks'):
-        for link in info['symlinks']:
-            if link.startswith('/dev/disk/by-path/'):
-                return link
-
-    return udev_device_get_name(info)
-
-def udev_device_get_sysfs_path(info):
-    return info['sysfs_path']
-
-def udev_device_get_major(info):
-    return int(info["MAJOR"])
-
-def udev_device_get_minor(info):
-    return int(info["MINOR"])
-
-def udev_device_get_md_level(info):
-    return info.get("MD_LEVEL")
-
-def udev_device_get_md_devices(info):
-    return int(info["MD_DEVICES"])
-
-def udev_device_get_md_uuid(info):
-    return info["MD_UUID"]
-
-def udev_device_get_md_container(info):
-    return info.get("MD_CONTAINER")
-
-def udev_device_get_md_name(info):
-    return info.get("MD_DEVNAME")
-
-def udev_device_get_vg_name(info):
-    return info['LVM2_VG_NAME']
-
-def udev_device_get_lv_vg_name(info):
-    return info['DM_VG_NAME']
-
-def udev_device_get_vg_uuid(info):
-    return info['LVM2_VG_UUID']
-
-def udev_device_get_vg_size(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_SIZE']) / 1024
-
-def udev_device_get_vg_free(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_FREE']) / 1024
-
-def udev_device_get_vg_extent_size(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_EXTENT_SIZE']) / 1024
-
-def udev_device_get_vg_extent_count(info):
-    return int(info['LVM2_VG_EXTENT_COUNT'])
-
-def udev_device_get_vg_free_extents(info):
-    return int(info['LVM2_VG_FREE_COUNT'])
-
-def udev_device_get_vg_pv_count(info):
-    return int(info['LVM2_PV_COUNT'])
-
-def udev_device_get_pv_pe_start(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_PE_START']) / 1024
-
-def udev_device_get_lv_names(info):
-    names = info['LVM2_LV_NAME']
-    if not names:
-        names = []
-    elif not isinstance(names, list):
-        names = [names]
-    return names
-
-def udev_device_get_lv_uuids(info):
-    uuids = info['LVM2_LV_UUID']
-    if not uuids:
-        uuids = []
-    elif not isinstance(uuids, list):
-        uuids = [uuids]
-    return uuids
-
-def udev_device_get_lv_sizes(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    sizes = info['LVM2_LV_SIZE']
-    if not sizes:
-        sizes = []
-    elif not isinstance(sizes, list):
-        sizes = [sizes]
-
-    return [float(s) / 1024 for s in sizes]
-
-def udev_device_get_lv_attr(info):
-    attr = info['LVM2_LV_ATTR']
-    if not attr:
-        attr = []
-    elif not isinstance(attr, list):
-        attr = [attr]
-    return attr
-
-def udev_device_dm_subsystem_match(info, subsystem):
-    """ Return True if the device matches a given device-mapper subsystem. """
-    uuid = info.get("DM_UUID", "")
-    uuid_fields = uuid.split("-")
-    _subsystem = uuid_fields[0]
-    if _subsystem.lower().startswith("part") and len(uuid_fields) > 1:
-        # kpartx uses partN- as a subsystem prefix, which we ignore because
-        # we only care about the subsystem of the partitions' parent device.
-        _subsystem = uuid_fields[1]
-
-    if _subsystem == uuid or not _subsystem:
-        return False
-
-    return _subsystem.lower() == subsystem.lower()
-
-def udev_device_is_dm_lvm(info):
-    """ Return True if the device is an LVM logical volume. """
-    return udev_device_dm_subsystem_match(info, "lvm")
-
-def udev_device_is_dm_crypt(info):
-    """ Return True if the device is a mapped dm-crypt device. """
-    return udev_device_dm_subsystem_match(info, "crypt")
-
-def udev_device_is_dm_luks(info):
-    """ Return True if the device is a mapped LUKS device. """
-    is_crypt = udev_device_dm_subsystem_match(info, "crypt")
-    try:
-        _type = info.get("DM_UUID", "").split("-")[1].lower()
-    except IndexError:
-        _type = ""
-
-    return is_crypt and _type.startswith("luks")
-
-def udev_device_is_dm_raid(info):
-    """ Return True if the device is a dmraid array device. """
-    return udev_device_dm_subsystem_match(info, "dmraid")
-
-def udev_device_is_dm_mpath(info):
-    """ Return True if the device is a multipath device. """
-    return udev_device_dm_subsystem_match(info, "mpath")
-
-def udev_device_is_dm_anaconda(info):
-    """ Return True if the device is an anaconda disk image. """
-    return udev_device_dm_subsystem_match(info, "anaconda")
-
-def udev_device_is_dm_livecd(info):
-    """ Return True if the device is a livecd OS image. """
-    # return udev_device_dm_subsystem_match(info, "livecd")
-    return (udev_device_is_dm(info) and
-            udev_device_get_name(info).startswith("live"))
-
-def udev_device_is_biosraid_member(info):
-    # Note that this function does *not* identify raid sets.
-    # Tests to see if device is part of a dmraid set.
-    # dmraid and mdraid have the same ID_FS_USAGE string, ID_FS_TYPE has a
-    # string that describes the type of dmraid (isw_raid_member...),  I don't
-    # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
-    # dmraid will be everything that is raid and not linux_raid_member
-    from formats.dmraid import DMRaidMember
-    from formats.mdraid import MDRaidMember
-    if info.has_key("ID_FS_TYPE") and \
-            (info["ID_FS_TYPE"] in DMRaidMember._udevTypes or \
-             info["ID_FS_TYPE"] in MDRaidMember._udevTypes) and \
-            info["ID_FS_TYPE"] != "linux_raid_member":
-        return True
-
-    return False
-
-def udev_device_get_dm_partition_disk(info):
-    return re.sub(r'\d*$', '', udev_device_get_name(info))
-
-def udev_device_is_dm_partition(info):
-    return (udev_device_is_dm(info) and
-            info.get("DM_UUID", "").split("-")[0].startswith("part"))
-
-def udev_device_is_multipath_member(info):
-    """ Return True if the device is part of a multipath. """
-    return info.get("ID_FS_TYPE") == "multipath_member"
-
-def udev_device_get_multipath_name(info):
-    """ Return the name of the multipath that the device is a member of. """
-    if udev_device_is_multipath_member(info):
-        return info['ID_MPATH_NAME']
-    return None
-
-# iscsi disks' ID_PATH form depends on the driver:
-# for software iscsi:
-# ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${lun}
-# for partial offload iscsi:
-# pci-${pci_address}-ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${lun}
-# Note that in the case of IPV6 iscsi_address itself can contain :
-# too, but iscsi_port never contains :
-
-def udev_device_is_sw_iscsi(info):
-    # software iscsi
-    try:
-        path_components = udev_device_get_path(info).split("-")
-
-        if info["ID_BUS"] == "scsi" and len(path_components) >= 6 and \
-                path_components[0] == "ip" and path_components[2] == "iscsi":
-            return True
-    except KeyError:
-        pass
-
-    return False
-
-def udev_device_is_partoff_iscsi(info):
-    # partial offload iscsi
-    try:
-        path_components = udev_device_get_path(info).split("-")
-
-        if info["ID_BUS"] == "scsi" and len(path_components) >= 8 and \
-                path_components[2] == "ip" and path_components[4] == "iscsi":
-            return True
-    except KeyError:
-        pass
-
-    return False
-
-def udev_device_is_iscsi(info):
-    return udev_device_is_sw_iscsi(info) or udev_device_is_partoff_iscsi(info)
-
-def udev_device_get_iscsi_name(info):
-    name_field = 3
-    if udev_device_is_partoff_iscsi(info):
-        name_field = 5
-
-    path_components = udev_device_get_path(info).split("-")
-
-    # Tricky, the name itself contains atleast 1 - char
-    return "-".join(path_components[name_field:len(path_components)-2])
-
-def udev_device_get_iscsi_address(info):
-    address_field = 1
-    if udev_device_is_partoff_iscsi(info):
-        address_field = 3
-
-    path_components = udev_device_get_path(info).split("-")
-
-    # IPV6 addresses contain : within the address, so take everything
-    # before the last : as address
-    return ":".join(path_components[address_field].split(":")[:-1])
-
-def udev_device_get_iscsi_port(info):
-    address_field = 1
-    if udev_device_is_partoff_iscsi(info):
-        address_field = 3
-
-    path_components = udev_device_get_path(info).split("-")
-
-    # IPV6 contains : within the address, the part after the last : is the port
-    return path_components[address_field].split(":")[-1]
-
-def udev_device_get_iscsi_session(info):
-    # '/devices/pci0000:00/0000:00:02.0/0000:09:00.0/0000:0a:01.0/0000:0e:00.2/host3/session1/target3:0:0/3:0:0:0/block/sda'
-    # The position of sessionX part depends on device
-    # (e.g. offload vs. sw; also varies for different offload devs)
-    session = None
-    match = re.match('/.*/(session\d+)', info["sysfs_path"])
-    if match:
-        session = match.groups()[0]
-    else:
-        log.error("udev_device_get_iscsi_session: session not found in %s" % info)
-    return session
-
-
-def udev_device_get_iscsi_nic(info):
-    iface = None
-    session = udev_device_get_iscsi_session(info)
-    if session:
-        iface = open("/sys/class/iscsi_session/%s/ifacename" %
-                     session).read().strip()
-    return iface
-
-def udev_device_get_iscsi_initiator(info):
-    initiator = None
-    if udev_device_is_partoff_iscsi(info):
-        host = re.match('.*/(host\d+)', info["sysfs_path"]).groups()[0]
-        if host:
-            initiator_file = "/sys/class/iscsi_host/%s/initiatorname" % host
-            if os.access(initiator_file, os.R_OK):
-                initiator = open(initiator_file).read().strip()
-                log.debug("found offload iscsi initiatorname %s in file %s" %
-                          (initiator, initiator_file))
-                if initiator.lstrip("(").rstrip(")").lower() == "null":
-                    initiator = None
-    if initiator is None:
-        session = udev_device_get_iscsi_session(info)
-        if session:
-            initiator = open("/sys/class/iscsi_session/%s/initiatorname" %
-                             session).read().strip()
-            log.debug("found iscsi initiatorname %s" % initiator)
-    return initiator
-
-
-# fcoe disks have ID_PATH in the form of:
-# For FCoE directly over the NIC (so no VLAN and thus no DCB):
-# pci-eth#-fc-${id}
-# For FCoE over a VLAN (the DCB case)
-# fc-${id}
-# fcoe parts look like this:
-# pci-eth#-fc-${id}-part#
-# fc-${id}-part#
-
-# For the FCoE over VLAN case we also do some checks on the sysfs_path as
-# the ID_PATH does not contain all info we need there, the sysfs_path for
-# an fcoe disk over VLAN looks like this:
-# /devices/virtual/net/eth4.802-fcoe/host3/rport-3:0-4/target3:0:1/3:0:1:0/block/sde
-# And for a partition:
-# /devices/virtual/net/eth4.802-fcoe/host3/rport-3:0-4/target3:0:1/3:0:1:0/block/sde/sde1
-
-# This is completely different for Broadcom FCoE devices (bnx2fc), where we use
-# the sysfs path:
-# /devices/pci0000:00/0000:00:02.0/0000:09:00.0/0000:0a:01.0/0000:0e:00.0/host3/rport-3:0-2/target3:0:1/3:0:1:3/block/sdm
-# and find whether the host has 'fc_host' and if it the device has a bound
-# Ethernet interface.
-
-def _detect_broadcom_fcoe(info):
-    re_pci_host=re.compile('/(.*)/(host\d+)')
-    match = re_pci_host.match(info["sysfs_path"])
-    if match:
-        sysfs_pci, host = match.groups()
-        if os.access('/sys/%s/%s/fc_host' %(sysfs_pci, host), os.X_OK) and \
-                os.access('/sys/%s/net' %(sysfs_pci), os.X_OK):
-            return (sysfs_pci, host)
-    return (None, None)
-
-def udev_device_is_fcoe(info):
-    if info.get("ID_BUS") != "scsi":
-        return False
-
-    path = info.get("ID_PATH", "")
-    path_components = path.split("-")
-
-    if path.startswith("pci-eth") and len(path_components) >= 4 and \
-       path_components[2] == "fc":
-        return True
-
-    if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
-        return True
-
-    if _detect_broadcom_fcoe(info) != (None, None):
-        return True
-
-    return False
-
-def udev_device_get_fcoe_nic(info):
-    path = info.get("ID_PATH", "")
-    path_components = path.split("-")
-
-    if path.startswith("pci-eth") and len(path_components) >= 4 and \
-       path_components[2] == "fc":
-        return path_components[1]
-
-    if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
-        return info["sysfs_path"].split("/")[4].split(".")[0]
-
-    (sysfs_pci, host) = _detect_broadcom_fcoe(info)
-    if (sysfs_pci, host) != (None, None):
-        net_path = '/sys/%s/net' % sysfs_pci
-        listdir = os.listdir(net_path)
-        if len(listdir) > 0 :
-            return listdir[0]
-
-def udev_device_get_fcoe_identifier(info):
-    path = info.get("ID_PATH", "")
-    path_components = path.split("-")
-
-    if path.startswith("pci-eth") and len(path_components) >= 4 and \
-       path_components[2] == "fc":
-        return path_components[3]
-
-    if path.startswith("fc-") and "fcoe" in info["sysfs_path"]:
-        return path_components[1]
-
-    if udev_device_is_fcoe(info) and len(path_components) >= 4 and \
-       path_components[2] == 'fc':
-        return path_components[3]
diff --git a/pyanaconda/storage/util.py b/pyanaconda/storage/util.py
deleted file mode 100644
index c80841b..0000000
--- a/pyanaconda/storage/util.py
+++ /dev/null
@@ -1,272 +0,0 @@
-import os
-import selinux
-import subprocess
-
-from size import Size
-
-import logging
-log = logging.getLogger("storage")
-program_log = logging.getLogger("program")
-
-def _run_program(argv, root='/', stdin=None, env_prune=None):
-    if env_prune is None:
-        env_prune = []
-
-    def chroot():
-        if root and root != '/':
-            os.chroot(root)
-
-    program_log.info("Running... %s" % argv)
-
-    env = os.environ.copy()
-    env.update({"LC_ALL": "C",
-                "INSTALL_PATH": root})
-    for var in env_prune:
-        env.pop(var, None)
-
-    try:
-        proc = subprocess.Popen(argv,
-                                stdin=stdin,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT,
-                                preexec_fn=chroot, cwd=root, env=env)
-
-        while True:
-            out = proc.communicate()[0]
-            if out:
-                for line in out.splitlines():
-                    program_log.info(line)
-
-            if proc.returncode is not None:
-                break
-    except OSError as e:
-        program_log.error("Error running %s: %s" % (argv[0], e.strerror))
-        raise
-
-    program_log.debug("Return code: %d" % proc.returncode)
-    return (proc.returncode, out)
-
-def run_program(*args, **kwargs):
-    return _run_program(*args, **kwargs)[0]
-
-def capture_output(*args, **kwargs):
-    return _run_program(*args, **kwargs)[1]
-
-def mount(device, mountpoint, fstype, options=None):
-    if options is None:
-        options = "defaults"
-
-    mountpoint = os.path.normpath(mountpoint)
-    if not os.path.exists(mountpoint):
-        makedirs(mountpoint)
-
-    argv = ["mount", "-t", fstype, "-o", options, device, mountpoint]
-    try:
-        rc = run_program(argv)
-    except OSError as e:
-        raise
-
-    return rc
-
-def umount(mountpoint):
-    try:
-        rc = run_program(["umount", mountpoint])
-    except OSError as e:
-        raise
-
-    return rc
-
-def total_memory():
-    """ Return the amount of system RAM in kilobytes. """
-    lines = open("/proc/meminfo").readlines()
-    for line in lines:
-        if line.startswith("MemTotal:"):
-            mem = long(line.split()[1])
-
-    return mem
-
-##
-## sysfs functions
-##
-def notify_kernel(path, action="change"):
-    """ Signal the kernel that the specified device has changed.
-
-        Exceptions raised: ValueError, IOError
-    """
-    log.debug("notifying kernel of '%s' event on device %s" % (action, path))
-    path = os.path.join(path, "uevent")
-    if not path.startswith("/sys/") or not os.access(path, os.W_OK):
-        log.debug("sysfs path '%s' invalid" % path)
-        raise ValueError("invalid sysfs path")
-
-    f = open(path, "a")
-    f.write("%s\n" % action)
-    f.close()
-
-def get_sysfs_attr(path, attr):
-    if not attr:
-        log.debug("get_sysfs_attr() called with attr=None")
-        return None
-
-    attribute = "/sys%s/%s" % (path, attr)
-    attribute = os.path.realpath(attribute)
-
-    if not os.path.isfile(attribute) and not os.path.islink(attribute):
-        log.warning("%s is not a valid attribute" % (attr,))
-        return None
-
-    return open(attribute, "r").read().strip()
-
-def get_sysfs_path_by_name(dev_node, class_name="block"):
-    """ Return sysfs path for a given device.
-
-        For a device node (e.g. /dev/vda2) get the respective sysfs path
-        (e.g. /sys/class/block/vda2). This also has to work for device nodes
-        that are in a subdirectory of /dev like '/dev/cciss/c0d0p1'.
-     """
-    dev_name = os.path.basename(dev_node)
-    if dev_node.startswith("/dev/"):
-        dev_name = dev_node[5:].replace("/", "!")
-    sysfs_class_dir = "/sys/class/%s" % class_name
-    dev_path = os.path.join(sysfs_class_dir, dev_name)
-    if os.path.exists(dev_path):
-        return dev_path
-    else:
-        raise RuntimeError("get_sysfs_path_by_name: Could not find sysfs path "
-                           "for '%s' (it is not at '%s')" % (dev_node, dev_path))
-
-##
-## SELinux functions
-##
-def match_path_context(path):
-    """ Return the default SELinux context for the given path. """
-    context = None
-    try:
-        context = selinux.matchpathcon(os.path.normpath(path), 0)[1]
-    except OSError as e:
-        log.info("failed to get default SELinux context for %s: %s" % (path, e))
-
-    return context
-
-def set_file_context(path, context, root=None):
-    """ Set the SELinux file context of a file.
-
-        Arguments:
-
-            path        filename string
-            context     context string
-
-        Keyword Arguments:
-
-            root        an optional chroot string
-
-        Return Value:
-
-            True if successful, False if not.
-    """
-    if root is None:
-        root = '/'
-
-    full_path = os.path.normpath("%s/%s" % (root, path))
-    if context is None or not os.access(full_path, os.F_OK):
-        return False
-
-    try:
-        rc = (selinux.lsetfilecon(full_path, context) == 0)
-    except OSError as e:
-        log.info("failed to set SELinux context for %s: %s" % (full_path, e))
-        rc = False
-
-    return rc
-
-def reset_file_context(path, root=None):
-    """ Restore the SELinux context of a file to its default value.
-
-        Arguments:
-
-            path        filename string
-
-        Keyword Arguments:
-
-            root        an optional chroot string
-
-        Return Value:
-
-            If successful, returns the file's new/default context.
-    """
-    context = match_path_context(path)
-    if context:
-        if set_file_context(path, context, root=root):
-            return context
-
-##
-## Miscellaneous
-##
-def find_program_in_path(prog, raise_on_error=False):
-    for d in os.environ["PATH"].split(os.pathsep):
-        full = os.path.join(d, prog)
-        if os.access(full, os.X_OK):
-            return full
-
-    if raise_on_error:
-        raise RuntimeError("Unable to locate a needed executable: '%s'" % prog)
-
-def makedirs(path):
-    if not os.path.isdir(path):
-        os.makedirs(path, 0755)
-
-def copy_to_system(source):
-    if not os.access(source, os.R_OK):
-        log.info("copy_to_system: source '%s' does not exist." % source)
-        return False
-
-    target = ROOT_PATH + source
-    target_dir = os.path.dirname(target)
-    log.debug("copy_to_system: '%s' -> '%s'." % (source, target))
-    if not os.path.isdir(target_dir):
-        os.makedirs(target_dir)
-    shutil.copy(source, target)
-    return True
-
-def lsmod():
-    """ Returns list of names of all loaded modules. """
-    with open("/proc/modules") as f:
-        lines = f.readlines()
-    return [l.split()[0] for l in lines]
-
-def get_option_value(opt_name, options):
-    """ Return the value of a named option in the specified options string. """
-    for opt in options.split(","):
-        if "=" not in opt:
-            continue
-
-        name, val = opt.split("=")
-        if name == opt_name:
-            return val.strip()
-
-def numeric_type(num):
-    """ Verify that a value is given as a numeric data type.
-
-        Return the number if the type is sensible or raise ValueError
-        if not.
-    """
-    if num is None:
-        num = 0
-    elif not (isinstance(num, int) or \
-              isinstance(num, long) or \
-              isinstance(num, float)):
-        raise ValueError("value (%s) must be either a number or None" % num)
-
-    return num
-
-def insert_colons(a_string):
-    """ Insert colon between every second character.
-
-        E.g. creates 'al:go:ri:th:ms' from 'algoritms'. Useful for formatting
-        MAC addresses and wwids for output.
-    """
-    suffix = a_string[-2:]
-    if len(a_string) > 2:
-        return insert_colons(a_string[:-2]) + ':' + suffix
-    else:
-        return suffix
diff --git a/pyanaconda/storage/zfcp.py b/pyanaconda/storage/zfcp.py
deleted file mode 100644
index 23be6cd..0000000
--- a/pyanaconda/storage/zfcp.py
+++ /dev/null
@@ -1,428 +0,0 @@
-#
-# zfcp.py - mainframe zfcp configuration install data
-#
-# Copyright (C) 2001, 2002, 2003, 2004  Red Hat, Inc.  All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Karsten Hopp <karsten@redhat.com>
-#
-
-import string
-import os
-from . import ROOT_PATH
-from udev import udev_settle
-from . import util
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def loggedWriteLineToFile(fn, value):
-    f = open(fn, "w")
-    log.debug("echo %s > %s" % (value, fn))
-    f.write("%s\n" % (value))
-    f.close()
-
-zfcpsysfs = "/sys/bus/ccw/drivers/zfcp"
-scsidevsysfs = "/sys/bus/scsi/devices"
-zfcpconf = "/etc/zfcp.conf"
-
-class ZFCPDevice:
-    def __init__(self, devnum, wwpn, fcplun):
-        self.devnum = self.sanitizeDeviceInput(devnum)
-        self.wwpn = self.sanitizeWWPNInput(wwpn)
-        self.fcplun = self.sanitizeFCPLInput(fcplun)
-
-        if not self.checkValidDevice(self.devnum):
-            raise ValueError, _("You have not specified a device number or the number is invalid")
-        if not self.checkValidWWPN(self.wwpn):
-            raise ValueError, _("You have not specified a worldwide port name or the name is invalid.")
-        if not self.checkValidFCPLun(self.fcplun):
-            raise ValueError, _("You have not specified a FCP LUN or the number is invalid.")
-
-    def __str__(self):
-        return "%s %s %s" %(self.devnum, self.wwpn, self.fcplun)
-
-    def sanitizeDeviceInput(self, dev):
-        if dev is None or dev == "":
-            return None
-        dev = dev.lower()
-        bus = dev[:string.rfind(dev, ".") + 1]
-        dev = dev[string.rfind(dev, ".") + 1:]
-        dev = "0" * (4 - len(dev)) + dev
-        if not len(bus):
-            return "0.0." + dev
-        else:
-            return bus + dev
-
-    def sanitizeWWPNInput(self, id):
-        if id is None or id == "":
-            return None
-        id = id.lower()
-        if id[:2] != "0x":
-            return "0x" + id
-        return id
-
-    # ZFCP LUNs are usually entered as 16 bit, sysfs accepts only 64 bit 
-    # (#125632), expand with zeroes if necessary
-    def sanitizeFCPLInput(self, lun):
-        if lun is None or lun == "":
-            return None
-        lun = lun.lower()
-        if lun[:2] == "0x":
-            lun = lun[2:]
-        lun = "0x" + "0" * (4 - len(lun)) + lun
-        lun = lun + "0" * (16 - len(lun) + 2)
-        return lun
-
-    def _hextest(self, hex):
-        try:
-            int(hex, 16)
-            return True
-        except TypeError:
-            return False
-
-    def checkValidDevice(self, id):
-        if id is None or id == "":
-            return False
-        if len(id) != 8:             # p.e. 0.0.0600
-            return False
-        if id[0] not in string.digits or id[2] not in string.digits:
-            return False
-        if id[1] != "." or id[3] != ".":
-            return False
-        return self._hextest(id[4:])
-
-    def checkValid64BitHex(self, hex):
-        if hex is None or hex == "":
-            return False
-        if len(hex) != 18:
-            return False
-        return self._hextest(hex)
-    checkValidWWPN = checkValidFCPLun = checkValid64BitHex
-
-    def onlineDevice(self):
-        online = "%s/%s/online" %(zfcpsysfs, self.devnum)
-        portadd = "%s/%s/port_add" %(zfcpsysfs, self.devnum)
-        portdir = "%s/%s/%s" %(zfcpsysfs, self.devnum, self.wwpn)
-        unitadd = "%s/unit_add" %(portdir)
-        unitdir = "%s/%s" %(portdir, self.fcplun)
-        failed = "%s/failed" %(unitdir)
-
-        if not os.path.exists(online):
-            log.info("Freeing zFCP device %s" % (self.devnum,))
-            util.run_program(["zfcp_cio_free", "-d", self.devnum])
-
-        if not os.path.exists(online):
-            raise ValueError, _(
-                "zFCP device %s not found, not even in device ignore list."
-                %(self.devnum,))
-
-        try:
-            f = open(online, "r")
-            devonline = f.readline().strip()
-            f.close()
-            if devonline != "1":
-                loggedWriteLineToFile(online, "1")
-        except IOError as e:
-            raise ValueError, _("Could not set zFCP device %(devnum)s "
-                                "online (%(e)s).") \
-                              % {'devnum': self.devnum, 'e': e}
-
-        if not os.path.exists(portdir):
-            if os.path.exists(portadd):
-                # older zfcp sysfs interface
-                try:
-                    loggedWriteLineToFile(portadd, self.wwpn)
-                    udev_settle()
-                except IOError as e:
-                    raise ValueError, _("Could not add WWPN %(wwpn)s to zFCP "
-                                        "device %(devnum)s (%(e)s).") \
-                                      % {'wwpn': self.wwpn,
-                                         'devnum': self.devnum,
-                                         'e': e}
-            else:
-                # newer zfcp sysfs interface with auto port scan
-                raise ValueError, _("WWPN %(wwpn)s not found at zFCP device "
-                                    "%(devnum)s.") % {'wwpn': self.wwpn,
-                                                      'devnum': self.devnum}
-        else:
-            if os.path.exists(portadd):
-                # older zfcp sysfs interface
-                log.info("WWPN %(wwpn)s at zFCP device %(devnum)s already "
-                         "there." % {'wwpn': self.wwpn,
-                                     'devnum': self.devnum})
-
-        if not os.path.exists(unitdir):
-            try:
-                loggedWriteLineToFile(unitadd, self.fcplun)
-                udev_settle()
-            except IOError as e:
-                raise ValueError, _("Could not add LUN %(fcplun)s to WWPN "
-                                    "%(wwpn)s on zFCP device %(devnum)s "
-                                    "(%(e)s).") \
-                                  % {'fcplun': self.fcplun, 'wwpn': self.wwpn,
-                                     'devnum': self.devnum, 'e': e}
-        else:
-            raise ValueError, _("LUN %(fcplun)s at WWPN %(wwpn)s on zFCP "
-                                "device %(devnum)s already configured.") \
-                              % {'fcplun': self.fcplun,
-                                 'wwpn': self.wwpn,
-                                 'devnum': self.devnum}
-
-        fail = "0"
-        try:
-            f = open(failed, "r")
-            fail = f.readline().strip()
-            f.close()
-        except IOError as e:
-            raise ValueError, _("Could not read failed attribute of LUN "
-                                "%(fcplun)s at WWPN %(wwpn)s on zFCP device "
-                                "%(devnum)s (%(e)s).") \
-                              % {'fcplun': self.fcplun,
-                                 'wwpn': self.wwpn,
-                                 'devnum': self.devnum,
-                                 'e': e}
-        if fail != "0":
-            self.offlineDevice()
-            raise ValueError, _("Failed LUN %(fcplun)s at WWPN %(wwpn)s on "
-                                "zFCP device %(devnum)s removed again.") \
-                              % {'fcplun': self.fcplun,
-                                 'wwpn': self.wwpn,
-                                 'devnum': self.devnum}
-
-        return True
-
-    def offlineSCSIDevice(self):
-        f = open("/proc/scsi/scsi", "r")
-        lines = f.readlines()
-        f.close()
-        # alternatively iterate over /sys/bus/scsi/devices/*:0:*:*/
-
-        for line in lines:
-            if not line.startswith("Host"):
-                continue
-            scsihost = string.split(line)
-            host = scsihost[1]
-            channel = "0"
-            id = scsihost[5]
-            lun = scsihost[7]
-            scsidev = "%s:%s:%s:%s" % (host[4:], channel, id, lun)
-            fcpsysfs = "%s/%s" % (scsidevsysfs, scsidev)
-            scsidel = "%s/%s/delete" % (scsidevsysfs, scsidev)
-
-            f = open("%s/hba_id" %(fcpsysfs), "r")
-            fcphbasysfs = f.readline().strip()
-            f.close()
-            f = open("%s/wwpn" %(fcpsysfs), "r")
-            fcpwwpnsysfs = f.readline().strip()
-            f.close()
-            f = open("%s/fcp_lun" %(fcpsysfs), "r")
-            fcplunsysfs = f.readline().strip()
-            f.close()
-
-            if fcphbasysfs == self.devnum \
-                    and fcpwwpnsysfs == self.wwpn \
-                    and fcplunsysfs == self.fcplun:
-                loggedWriteLineToFile(scsidel, "1")
-                udev_settle()
-                return
-
-        log.warn("no scsi device found to delete for zfcp %s %s %s"
-                 %(self.devnum, self.wwpn, self.fcplun))
-
-    def offlineDevice(self):
-        offline = "%s/%s/online" %(zfcpsysfs, self.devnum)
-        portadd = "%s/%s/port_add" %(zfcpsysfs, self.devnum)
-        portremove = "%s/%s/port_remove" %(zfcpsysfs, self.devnum)
-        unitremove = "%s/%s/%s/unit_remove" %(zfcpsysfs, self.devnum, self.wwpn)
-        portdir = "%s/%s/%s" %(zfcpsysfs, self.devnum, self.wwpn)
-        devdir = "%s/%s" %(zfcpsysfs, self.devnum)
-
-        try:
-            self.offlineSCSIDevice()
-        except IOError as e:
-            raise ValueError, _("Could not correctly delete SCSI device of "
-                                "zFCP %(devnum)s %(wwpn)s %(fcplun)s "
-                                "(%(e)s).") \
-                              % {'devnum': self.devnum, 'wwpn': self.wwpn,
-                                 'fcplun': self.fcplun, 'e': e}
-
-        try:
-            loggedWriteLineToFile(unitremove, self.fcplun)
-        except IOError as e:
-            raise ValueError, _("Could not remove LUN %(fcplun)s at WWPN "
-                                "%(wwpn)s on zFCP device %(devnum)s "
-                                "(%(e)s).") \
-                              % {'fcplun': self.fcplun, 'wwpn': self.wwpn,
-                                 'devnum': self.devnum, 'e': e}
-
-        if os.path.exists(portadd):
-            # only try to remove ports with older zfcp sysfs interface
-            for lun in os.listdir(portdir):
-                if lun.startswith("0x") and \
-                        os.path.isdir(os.path.join(portdir, lun)):
-                    log.info("Not removing WWPN %s at zFCP device %s since port still has other LUNs, e.g. %s."
-                             %(self.wwpn, self.devnum, lun))
-                    return True
-
-            try:
-                loggedWriteLineToFile(portremove, self.wwpn)
-            except IOError as e:
-                raise ValueError, _("Could not remove WWPN %(wwpn)s on zFCP "
-                                    "device %(devnum)s (%(e)s).") \
-                                  % {'wwpn': self.wwpn,
-                                     'devnum': self.devnum, 'e': e}
-
-        if os.path.exists(portadd):
-            # older zfcp sysfs interface
-            for port in os.listdir(devdir):
-                if port.startswith("0x") and \
-                        os.path.isdir(os.path.join(devdir, port)):
-                    log.info("Not setting zFCP device %s offline since it still has other ports, e.g. %s."
-                             %(self.devnum, port))
-                    return True
-        else:
-            # newer zfcp sysfs interface with auto port scan
-            import glob
-            luns = glob.glob("%s/0x????????????????/0x????????????????"
-                          %(devdir,))
-            if len(luns) != 0:
-                log.info("Not setting zFCP device %s offline since it still has other LUNs, e.g. %s."
-                         %(self.devnum, luns[0]))
-                return True
-
-        try:
-            loggedWriteLineToFile(offline, "0")
-        except IOError as e:
-            raise ValueError, _("Could not set zFCP device %(devnum)s "
-                                "offline (%(e)s).") \
-                              % {'devnum': self.devnum, 'e': e}
-
-        return True
-
-class ZFCP:
-    """ ZFCP utility class.
-
-        This class will automatically online to ZFCP drives configured in
-        /tmp/fcpconfig when the startup() method gets called. It can also be
-        used to manually configure ZFCP devices through the addFCP() method.
-
-        As this class needs to make sure that /tmp/fcpconfig configured
-        drives are only onlined once and as it keeps a global list of all ZFCP
-        devices it is implemented as a Singleton.
-    """
-
-    def __init__(self):
-        self.intf = None
-        self.fcpdevs = set()
-        self.hasReadConfig = False
-        self.down = True
-
-    # So that users can write zfcp() to get the singleton instance
-    def __call__(self):
-        return self
-
-    def readConfig(self):
-        try:
-            f = open(zfcpconf, "r")
-        except IOError:
-            log.info("no %s; not configuring zfcp" % (zfcpconf,))
-            return
-
-        lines = map(lambda x: x.strip().lower(), f.readlines())
-        f.close()
-
-        for line in lines:
-            if line.startswith("#") or line == '':
-                continue
-
-            fields = line.split()
-
-            if len(fields) == 3:
-                devnum = fields[0]
-                wwpn   = fields[1]
-                fcplun = fields[2]
-            elif len(fields) == 5:
-                # support old syntax of:
-                # devno scsiid wwpn scsilun fcplun
-                devnum = fields[0]
-                wwpn   = fields[2]
-                fcplun = fields[4]
-            else:
-                log.warn("Invalid line found in %s: %s" % (zfcpconf, line,))
-                continue
-
-            try:
-                self.addFCP(devnum, wwpn, fcplun)
-            except ValueError as e:
-                if self.intf:
-                    self.intf.messageWindow(_("Error"), str(e))
-                else:
-                    log.warning(str(e))
-
-    def addFCP(self, devnum, wwpn, fcplun):
-        d = ZFCPDevice(devnum, wwpn, fcplun)
-        if d.onlineDevice():
-            self.fcpdevs.add(d)
-
-    def shutdown(self):
-        if self.down:
-            return
-        self.down = True
-        if len(self.fcpdevs) == 0:
-            return
-        for d in self.fcpdevs:
-            try:
-                d.offlineDevice()
-            except ValueError as e:
-                log.warn(str(e))
-
-    def startup(self):
-        if not self.down:
-            return
-        self.down = False
-        if not self.hasReadConfig:
-            self.readConfig()
-            self.hasReadConfig = True
-            # readConfig calls addFCP which calls onlineDevice already
-            return
-
-        if len(self.fcpdevs) == 0:
-            return
-        for d in self.fcpdevs:
-            try:
-                d.onlineDevice()
-            except ValueError as e:
-                log.warn(str(e))
-
-    def write(self):
-        if len(self.fcpdevs) == 0:
-            return
-        f = open(ROOT_PATH + zfcpconf, "w")
-        for d in self.fcpdevs:
-            f.write("%s\n" %(d,))
-        f.close()
-        
-        f = open(ROOT_PATH + "/etc/modprobe.conf", "a")
-        f.write("alias scsi_hostadapter zfcp\n")
-        f.close()
-
-# Create ZFCP singleton
-ZFCP = ZFCP()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/timezone.py b/pyanaconda/timezone.py
index 01edeb3..ff9e3f3 100644
--- a/pyanaconda/timezone.py
+++ b/pyanaconda/timezone.py
@@ -30,7 +30,7 @@ from collections import OrderedDict
 
 from pyanaconda import localization
 from pyanaconda import iutil
-from pyanaconda.storage import arch
+from blivet import arch
 
 import logging
 log = logging.getLogger("anaconda")
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index d14f6ba..c799b7f 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -49,29 +49,29 @@ from pykickstart.constants import *
 from pyanaconda.product import productName, productVersion
 from pyanaconda.threads import threadMgr
 
-from pyanaconda.storage.formats import device_formats
-from pyanaconda.storage.formats import getFormat
-from pyanaconda.storage.formats.fs import FS
-from pyanaconda.storage.size import Size
-from pyanaconda.storage import Root
-from pyanaconda.storage import DEVICE_TYPE_LVM
-from pyanaconda.storage import DEVICE_TYPE_BTRFS
-from pyanaconda.storage import DEVICE_TYPE_PARTITION
-from pyanaconda.storage import DEVICE_TYPE_MD
-from pyanaconda.storage import DEVICE_TYPE_DISK
-from pyanaconda.storage import getDeviceType
-from pyanaconda.storage import getRAIDLevel
-from pyanaconda.storage import findExistingInstallations
-from pyanaconda.storage.partitioning import doPartitioning
-from pyanaconda.storage.partitioning import doAutoPartition
-from pyanaconda.storage.errors import StorageError
-from pyanaconda.storage.errors import NoDisksError
-from pyanaconda.storage.errors import NotEnoughFreeSpaceError
-from pyanaconda.storage.errors import ErrorRecoveryFailure
-from pyanaconda.storage.errors import CryptoError
-from pyanaconda.storage.errors import MDRaidError
-from pyanaconda.storage.devicelibs import mdraid
-from pyanaconda.storage.devices import LUKSDevice
+from blivet.formats import device_formats
+from blivet.formats import getFormat
+from blivet.formats.fs import FS
+from blivet.size import Size
+from blivet import Root
+from blivet import DEVICE_TYPE_LVM
+from blivet import DEVICE_TYPE_BTRFS
+from blivet import DEVICE_TYPE_PARTITION
+from blivet import DEVICE_TYPE_MD
+from blivet import DEVICE_TYPE_DISK
+from blivet import getDeviceType
+from blivet import getRAIDLevel
+from blivet import findExistingInstallations
+from blivet.partitioning import doPartitioning
+from blivet.partitioning import doAutoPartition
+from blivet.errors import StorageError
+from blivet.errors import NoDisksError
+from blivet.errors import NotEnoughFreeSpaceError
+from blivet.errors import ErrorRecoveryFailure
+from blivet.errors import CryptoError
+from blivet.errors import MDRaidError
+from blivet.devicelibs import mdraid
+from blivet.devices import LUKSDevice
 
 from pyanaconda.ui import communication
 from pyanaconda.ui.gui import GUIObject
diff --git a/pyanaconda/ui/gui/spokes/lib/cart.py b/pyanaconda/ui/gui/spokes/lib/cart.py
index 76d3649..bdc4faf 100644
--- a/pyanaconda/ui/gui/spokes/lib/cart.py
+++ b/pyanaconda/ui/gui/spokes/lib/cart.py
@@ -23,7 +23,7 @@
 from gi.repository import Gtk
 
 from pyanaconda.ui.gui import GUIObject
-from pyanaconda.storage.size import Size
+from blivet.size import Size
 
 import gettext
 
diff --git a/pyanaconda/ui/gui/spokes/lib/resize.py b/pyanaconda/ui/gui/spokes/lib/resize.py
index 0753331..ff6e014 100644
--- a/pyanaconda/ui/gui/spokes/lib/resize.py
+++ b/pyanaconda/ui/gui/spokes/lib/resize.py
@@ -24,7 +24,7 @@ from __future__ import division
 from gi.repository import Gtk
 
 from pyanaconda.ui.gui import GUIObject
-from pyanaconda.storage.size import Size
+from blivet.size import Size
 
 import gettext
 
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 955c9c6..a17feea 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -51,9 +51,9 @@ from pyanaconda.ui.gui.categories.storage import StorageCategory
 from pyanaconda.ui.gui.utils import enlightbox, gtk_call_once, gtk_thread_wait
 
 from pyanaconda.kickstart import doKickstartStorage
-from pyanaconda.storage.size import Size
-from pyanaconda.storage.errors import StorageError
-from pyanaconda.storage.platform import platform
+from blivet.size import Size
+from blivet.errors import StorageError
+from blivet.platform import platform
 from pyanaconda.threads import threadMgr, AnacondaThread
 from pyanaconda.product import productName
 from pyanaconda.flags import flags
diff --git a/pyanaconda/ui/gui/tools/run-spoke.py b/pyanaconda/ui/gui/tools/run-spoke.py
index 92173e7..5f85907 100755
--- a/pyanaconda/ui/gui/tools/run-spoke.py
+++ b/pyanaconda/ui/gui/tools/run-spoke.py
@@ -27,7 +27,7 @@ from pyanaconda import anaconda_log
 anaconda_log.init()
 
 from pyanaconda.installclass import DefaultInstall
-from pyanaconda.storage import Storage
+from blivet import Blivet
 from pyanaconda.threads import initThreading
 from pyanaconda.packaging.yumpayload import YumPayload
 from pykickstart.version import makeVersion
@@ -89,7 +89,7 @@ if not spokeClass:
 print "Running %s %s from %s" % (spokeText, spokeClass, spokeModule)
 
 ksdata = makeVersion()
-storage = Storage(data=ksdata)
+storage = Blivet(ksdata=ksdata)
 storage.reset()
 instclass = DefaultInstall()
 
diff --git a/pyanaconda/ui/lib/space.py b/pyanaconda/ui/lib/space.py
index c7601d3..44d1e3c 100644
--- a/pyanaconda/ui/lib/space.py
+++ b/pyanaconda/ui/lib/space.py
@@ -19,7 +19,7 @@
 # Red Hat Author(s): David Lehman <dlehman@redhat.com>
 #
 
-from pyanaconda.storage.size import Size
+from blivet.size import Size
 
 import gettext
 
diff --git a/pyanaconda/ui/tui/spokes/storage.py b/pyanaconda/ui/tui/spokes/storage.py
index b5d483f..7a5b9df 100644
--- a/pyanaconda/ui/tui/spokes/storage.py
+++ b/pyanaconda/ui/tui/spokes/storage.py
@@ -26,8 +26,8 @@ from pyanaconda.ui.tui.spokes import NormalTUISpoke
 from pyanaconda.ui.tui.simpleline import TextWidget, CheckboxWidget
 
 from pykickstart.constants import AUTOPART_TYPE_LVM
-from pyanaconda.storage.size import Size
-from pyanaconda.storage.errors import StorageError
+from blivet.size import Size
+from blivet.errors import StorageError
 from pyanaconda.flags import flags
 from pyanaconda.kickstart import doKickstartStorage
 from pyanaconda.threads import threadMgr, AnacondaThread
diff --git a/pyanaconda/ui/tui/tools/run-text-spoke.py b/pyanaconda/ui/tui/tools/run-text-spoke.py
index bc132f8..09c91a3 100755
--- a/pyanaconda/ui/tui/tools/run-text-spoke.py
+++ b/pyanaconda/ui/tui/tools/run-text-spoke.py
@@ -13,7 +13,7 @@ from pyanaconda import anaconda_log
 anaconda_log.init()
 
 from pyanaconda.installclass import DefaultInstall
-from pyanaconda.storage import Storage
+from blivet import Blivet
 from pyanaconda.threads import initThreading
 from pyanaconda.packaging.yumpayload import YumPayload
 from pykickstart.version import makeVersion
@@ -79,7 +79,7 @@ if not spokeClass:
 print "Running %s %s from %s" % (spokeText, spokeClass, spokeModule)
 
 ksdata = makeVersion()
-storage = Storage(data=ksdata)
+storage = Blivet(ksdata=ksdata)
 storage.reset()
 instclass = DefaultInstall()
 app = App("TEST HARNESS", yes_or_no_question = YesNoDialog)
diff --git a/scripts/anaconda-cleanup b/scripts/anaconda-cleanup
index b8a3487..1682f59 100755
--- a/scripts/anaconda-cleanup
+++ b/scripts/anaconda-cleanup
@@ -40,9 +40,9 @@ pyanaconda.anaconda_log.init()
 
 from pyanaconda import iutil
 
-from pyanaconda.storage import StorageDiscoveryConfig
-from pyanaconda.storage.devicetree import DeviceTree
-from pyanaconda.storage import devicelibs
+from blivet import StorageDiscoveryConfig
+from blivet.devicetree import DeviceTree
+from blivet import devicelibs
 
 storage_config = StorageDiscoveryConfig()
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index df244c9..cb4c701 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -17,6 +17,6 @@
 #
 # Author: David Cantrell <dcantrell@redhat.com>
 
-SUBDIRS = mock kickstart_test storage_test regex pyanaconda_test pylint logpicker_test
+SUBDIRS = mock kickstart_test regex pyanaconda_test pylint logpicker_test
 
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/tests/storage_test/Makefile.am b/tests/storage_test/Makefile.am
deleted file mode 100644
index 23565ab..0000000
--- a/tests/storage_test/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# tests/storage/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@redhat.com>
-
-SUBDIRS = devicelibs_test
-
-EXTRA_DIST = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/tests/storage_test/action_test.py b/tests/storage_test/action_test.py
deleted file mode 100644
index b07a44b..0000000
--- a/tests/storage_test/action_test.py
+++ /dev/null
@@ -1,926 +0,0 @@
-#!/usr/bin/python
-
-import unittest
-from mock import Mock
-from mock import TestCase
-
-from storagetestcase import StorageTestCase
-import pyanaconda.storage as storage
-from pyanaconda.storage.formats import getFormat
-
-# device classes for brevity's sake -- later on, that is
-from pyanaconda.storage.devices import StorageDevice
-from pyanaconda.storage.devices import DiskDevice
-from pyanaconda.storage.devices import PartitionDevice
-from pyanaconda.storage.devices import MDRaidArrayDevice
-from pyanaconda.storage.devices import DMDevice
-from pyanaconda.storage.devices import LUKSDevice
-from pyanaconda.storage.devices import LVMVolumeGroupDevice
-from pyanaconda.storage.devices import LVMLogicalVolumeDevice
-from pyanaconda.storage.devices import FileDevice
-
-# action classes
-from pyanaconda.storage.deviceaction import ActionCreateDevice
-from pyanaconda.storage.deviceaction import ActionResizeDevice
-from pyanaconda.storage.deviceaction import ActionDestroyDevice
-from pyanaconda.storage.deviceaction import ActionCreateFormat
-from pyanaconda.storage.deviceaction import ActionResizeFormat
-from pyanaconda.storage.deviceaction import ActionMigrateFormat
-from pyanaconda.storage.deviceaction import ActionDestroyFormat
-
-""" DeviceActionTestSuite """
-
-class DeviceActionTestCase(StorageTestCase):
-    def setUp(self):
-        """ Create something like a preexisting autopart on two disks (sda,sdb).
-
-            The other two disks (sdc,sdd) are left for individual tests to use.
-        """
-        self.setUpAnaconda()
-
-        for name in ["sda", "sdb", "sdc", "sdd"]:
-            disk = self.newDevice(device_class=DiskDevice,
-                                  name=name, size=100000)
-            disk.format = self.newFormat("disklabel", path=disk.path,
-                                         exists=True)
-            self.storage.devicetree._addDevice(disk)
-
-        # create a layout similar to autopart as a starting point
-        sda = self.storage.devicetree.getDeviceByName("sda")
-        sdb = self.storage.devicetree.getDeviceByName("sdb")
-
-        sda1 = self.newDevice(device_class=PartitionDevice,
-                              exists=True, name="sda1", parents=[sda], size=500)
-        sda1.format = self.newFormat("ext4", mountpoint="/boot",
-                                     device_instance=sda1,
-                                     device=sda1.path, exists=True)
-        self.storage.devicetree._addDevice(sda1)
-
-        sda2 = self.newDevice(device_class=PartitionDevice,
-                              size=99500, name="sda2", parents=[sda], exists=True)
-        sda2.format = self.newFormat("lvmpv", device=sda2.path, exists=True)
-        self.storage.devicetree._addDevice(sda2)
-
-        sdb1 = self.newDevice(device_class=PartitionDevice,
-                              size=99999, name="sdb1", parents=[sdb], exists=True)
-        sdb1.format = self.newFormat("lvmpv", device=sdb1.path, exists=True)
-        self.storage.devicetree._addDevice(sdb1)
-
-        vg = self.newDevice(device_class=LVMVolumeGroupDevice,
-                            name="VolGroup", parents=[sda2, sdb1],
-                            exists=True)
-        self.storage.devicetree._addDevice(vg)
-
-        lv_root = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_root", vgdev=vg, size=160000,
-                                 exists=True)
-        lv_root.format = self.newFormat("ext4", mountpoint="/",
-                                        device_instance=lv_root,
-                                        device=lv_root.path, exists=True)
-        self.storage.devicetree._addDevice(lv_root)
-
-        lv_swap = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_swap", vgdev=vg, size=4000,
-                                 exists=True)
-        lv_swap.format = self.newFormat("swap", device=lv_swap.path,
-                                        device_instance=lv_swap,
-                                        exists=True)
-        self.storage.devicetree._addDevice(lv_swap)
-
-    def testActions(self, *args, **kwargs):
-        """ Verify correct management of actions.
-
-            - action creation/registration/cancellation
-                - ActionCreateDevice adds device to tree
-                - ActionDestroyDevice removes device from tree
-                - ActionCreateFormat sets device.format in tree
-                - ActionDestroyFormat unsets device.format in tree
-                - cancelled action's registration side-effects reversed
-                - failure to register destruction of non-leaf device
-                - failure to register creation of device already in tree?
-                - failure to register destruction of device not in tree?
-
-            - action pruning
-                - non-existent-device create..destroy cycles removed
-                    - all actions on this device should get removed
-                - all actions pruned from to-be-destroyed devices
-                    - resize, format, migrate, &c
-                - redundant resize/migrate/format actions pruned
-                    - last one registered stays
-
-            - action sorting
-                - destroy..resize..migrate..create
-                - creation
-                    - leaves-last, including formatting
-                - destruction
-                    - leaves-first
-        """
-        devicetree = self.storage.devicetree
-
-        # clear the disks
-        self.destroyAllDevices()
-        self.assertEqual(devicetree.getDevicesByType("lvmlv"), [])
-        self.assertEqual(devicetree.getDevicesByType("lvmvg"), [])
-        self.assertEqual(devicetree.getDevicesByType("partition"), [])
-
-        sda = devicetree.getDeviceByName("sda")
-        self.assertNotEqual(sda, None, "failed to find disk 'sda'")
-
-        sda1 = self.newDevice(device_class=PartitionDevice,
-                              name="sda1", size=500, parents=[sda])
-        self.scheduleCreateDevice(device=sda1)
-
-        sda2 = self.newDevice(device_class=PartitionDevice,
-                              name="sda2", size=100000, parents=[sda])
-        self.scheduleCreateDevice(device=sda2)
-        format = self.newFormat("lvmpv", device=sda2.path)
-        self.scheduleCreateFormat(device=sda2, format=format)
-
-        vg = self.newDevice(device_class=LVMVolumeGroupDevice,
-                            name="vg", parents=[sda2])
-        self.scheduleCreateDevice(device=vg)
-
-        lv_root = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_root", vgdev=vg, size=60000)
-        self.scheduleCreateDevice(device=lv_root)
-        format = self.newFormat("ext4", device=lv_root.path, mountpoint="/")
-        self.scheduleCreateFormat(device=lv_root, format=format)
-
-        lv_swap = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_swap", vgdev=vg, size=4000)
-        self.scheduleCreateDevice(device=lv_swap)
-        format = self.newFormat("swap", device=lv_swap.path)
-        self.scheduleCreateFormat(device=lv_swap, format=format)
-
-        sda3 = self.newDevice(device_class=PartitionDevice,
-                              name="sda3", parents=[sda], size=40000)
-        self.scheduleCreateDevice(device=sda3)
-        format = self.newFormat("mdmember", device=sda3.path)
-        self.scheduleCreateFormat(device=sda3, format=format)
-
-        sdb = devicetree.getDeviceByName("sdb")
-        self.assertNotEqual(sdb, None, "failed to find disk 'sdb'")
-
-        sdb1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdb1", parents=[sdb], size=40000)
-        self.scheduleCreateDevice(device=sdb1)
-        format = self.newFormat("mdmember", device=sdb1.path,)
-        self.scheduleCreateFormat(device=sdb1, format=format)
-
-        md0 = self.newDevice(device_class=MDRaidArrayDevice,
-                             name="md0", level="raid0", minor=0, size=80000,
-                             memberDevices=2, totalDevices=2,
-                             parents=[sdb1, sda3])
-        self.scheduleCreateDevice(device=md0)
-
-        format = self.newFormat("ext4", device=md0.path, mountpoint="/home")
-        self.scheduleCreateFormat(device=md0, format=format)
-
-        format = self.newFormat("ext4", mountpoint="/boot", device=sda1.path)
-        self.scheduleCreateFormat(device=sda1, format=format)
-
-    def testActionCreation(self, *args, **kwargs):
-        """ Verify correct operation of action class constructors. """
-        # instantiation of device resize action for non-existent device should
-        # fail
-        # XXX resizable depends on existence, so this is covered implicitly
-        sdd = self.storage.devicetree.getDeviceByName("sdd")
-        p = self.newDevice(device_class=PartitionDevice,
-                           name="sdd1", size=32768, parents=[sdd])
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionResizeDevice,
-                              p,
-                              p.size + 7232)
-
-        # instantiation of device resize action for non-resizable device
-        # should fail
-        vg = self.storage.devicetree.getDeviceByName("VolGroup")
-        self.assertNotEqual(vg, None)
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionResizeDevice,
-                              vg,
-                              vg.size + 32)
-
-        # instantiation of format resize action for non-resizable format type
-        # should fail
-        lv_swap = self.storage.devicetree.getDeviceByName("VolGroup-lv_swap")
-        self.assertNotEqual(lv_swap, None)
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionResizeFormat,
-                              lv_swap,
-                              lv_swap.size + 32)
-
-        # instantiation of format resize action for non-existent format
-        # should fail
-        lv_root = self.storage.devicetree.getDeviceByName("VolGroup-lv_root")
-        self.assertNotEqual(lv_root, None)
-        lv_root.format.exists = False
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionResizeFormat,
-                              lv_root,
-                              lv_root.size - 1000)
-        lv_root.format.exists = True
-
-        # instantiation of format migrate action for non-migratable format
-        # type should fail
-        lv_swap = self.storage.devicetree.getDeviceByName("VolGroup-lv_swap")
-        self.assertNotEqual(lv_swap, None)
-        self.assertEqual(lv_swap.exists, True)
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionMigrateFormat,
-                              lv_swap)
-
-        # instantiation of format migrate for non-existent format should fail
-        lv_root = self.storage.devicetree.getDeviceByName("VolGroup-lv_root")
-        self.assertNotEqual(lv_root, None)
-        orig_format = lv_root.format
-        lv_root.format = getFormat("ext3", device=lv_root.path)
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionMigrateFormat,
-                              lv_root)
-        lv_root.format = orig_format
-
-        # instantiation of device create action for existing device should
-        # fail
-        lv_swap = self.storage.devicetree.getDeviceByName("VolGroup-lv_swap")
-        self.assertNotEqual(lv_swap, None)
-        self.assertEqual(lv_swap.exists, True)
-        self.failUnlessRaises(ValueError,
-                              storage.deviceaction.ActionCreateDevice,
-                              lv_swap)
-
-        # instantiation of format destroy action for device causes device's
-        # format attribute to be a DeviceFormat instance
-        lv_swap = self.storage.devicetree.getDeviceByName("VolGroup-lv_swap")
-        self.assertNotEqual(lv_swap, None)
-        orig_format = lv_swap.format
-        self.assertEqual(lv_swap.format.type, "swap")
-        a = storage.deviceaction.ActionDestroyFormat(lv_swap)
-        self.assertEqual(lv_swap.format.type, None)
-
-        # instantiation of format create action for device causes new format
-        # to be accessible via device's format attribute
-        new_format = getFormat("vfat", device=lv_swap.path)
-        a = storage.deviceaction.ActionCreateFormat(lv_swap, new_format)
-        self.assertEqual(lv_swap.format, new_format)
-        lv_swap.format = orig_format
-
-    def testActionRegistration(self, *args, **kwargs):
-        """ Verify correct operation of action registration and cancelling. """
-        # self.setUp has just been run, so we should have something like
-        # a preexisting autopart config in the devicetree.
-
-        # registering a destroy action for a non-leaf device should fail
-        vg = self.storage.devicetree.getDeviceByName("VolGroup")
-        self.assertNotEqual(vg, None)
-        self.assertEqual(vg.isleaf, False)
-        a = storage.deviceaction.ActionDestroyDevice(vg)
-        self.failUnlessRaises(ValueError,
-                              self.storage.devicetree.registerAction,
-			      a)
-
-        # registering any action other than create for a device that's not in
-        # the devicetree should fail
-        sdc = self.storage.devicetree.getDeviceByName("sdc")
-        self.assertNotEqual(sdc, None)
-        sdc1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc1", size=100000, parents=[sdc],
-                              exists=True)
-
-        sdc1_format = self.newFormat("ext2", device=sdc1.path, mountpoint="/")
-        create_sdc1_format = ActionCreateFormat(sdc1, sdc1_format)
-        self.failUnlessRaises(storage.errors.DeviceTreeError,
-                              self.storage.devicetree.registerAction,
-                              create_sdc1_format)
-
-        sdc1_format.exists = True
-
-        migrate_sdc1 = ActionMigrateFormat(sdc1)
-        self.failUnlessRaises(storage.errors.DeviceTreeError,
-                              self.storage.devicetree.registerAction,
-                              migrate_sdc1)
-        migrate_sdc1.cancel()
-
-        resize_sdc1_format = ActionResizeFormat(sdc1, sdc1.size - 10000)
-        self.failUnlessRaises(storage.errors.DeviceTreeError,
-                              self.storage.devicetree.registerAction,
-                              resize_sdc1_format)
-
-        resize_sdc1 = ActionResizeDevice(sdc1, sdc1.size - 10000)
-        self.failUnlessRaises(storage.errors.DeviceTreeError,
-                              self.storage.devicetree.registerAction,
-                              resize_sdc1)
-
-        resize_sdc1.cancel()
-        resize_sdc1_format.cancel()
-
-        destroy_sdc1_format = ActionDestroyFormat(sdc1)
-        self.failUnlessRaises(storage.errors.DeviceTreeError,
-                              self.storage.devicetree.registerAction,
-                              destroy_sdc1_format)
-
-
-        destroy_sdc1 = ActionDestroyDevice(sdc1)
-        self.failUnlessRaises(storage.errors.DeviceTreeError,
-                              self.storage.devicetree.registerAction,
-                              resize_sdc1)
-
-        # registering a device destroy action should cause the device to be
-        # removed from the devicetree
-        lv_root = self.storage.devicetree.getDeviceByName("VolGroup-lv_root")
-        self.assertNotEqual(lv_root, None)
-        a = ActionDestroyDevice(lv_root)
-        self.storage.devicetree.registerAction(a)
-        lv_root = self.storage.devicetree.getDeviceByName("VolGroup-lv_root")
-        self.assertEqual(lv_root, None)
-        self.storage.devicetree.cancelAction(a)
-
-        # registering a device create action should cause the device to be
-        # added to the devicetree
-        sdd = self.storage.devicetree.getDeviceByName("sdd")
-        self.assertNotEqual(sdd, None)
-        sdd1 = self.storage.devicetree.getDeviceByName("sdd1")
-        self.assertEqual(sdd1, None)
-        sdd1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdd1", size=100000, parents=[sdd])
-        a = ActionCreateDevice(sdd1)
-        self.storage.devicetree.registerAction(a)
-        sdd1 = self.storage.devicetree.getDeviceByName("sdd1")
-        self.assertNotEqual(sdd1, None)
-
-    def testActionObsoletes(self, *args, **kwargs):
-        """ Verify correct operation of DeviceAction.obsoletes. """
-        self.destroyAllDevices(disks=["sdc"])
-        sdc = self.storage.devicetree.getDeviceByName("sdc")
-        self.assertNotEqual(sdc, None)
-
-        sdc1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc1", parents=[sdc], size=40000)
-
-        # ActionCreateDevice
-        #
-        # - obsoletes other ActionCreateDevice instances w/ lower id and same
-        #   device
-        create_device_1 = ActionCreateDevice(sdc1)
-        create_device_2 = ActionCreateDevice(sdc1)
-        self.assertEqual(create_device_2.obsoletes(create_device_1), True)
-        self.assertEqual(create_device_1.obsoletes(create_device_2), False)
-
-        # ActionCreateFormat
-        #
-        # - obsoletes other ActionCreateFormat instances w/ lower id and same
-        #   device
-        format_1 = self.newFormat("ext3", mountpoint="/home", device=sdc1.path)
-        format_2 = self.newFormat("ext3", mountpoint="/opt", device=sdc1.path)
-        create_format_1 = ActionCreateFormat(sdc1, format_1)
-        create_format_2 = ActionCreateFormat(sdc1, format_2)
-        self.assertEqual(create_format_2.obsoletes(create_format_1), True)
-        self.assertEqual(create_format_1.obsoletes(create_format_2), False)
-
-        # ActionMigrateFormat
-        #
-        # - obsoletes other ActionMigrateFormat instances w/ lower id and same
-        #   device
-        sdc1.format = self.newFormat("ext2", mountpoint="/", device=sdc1.path,
-                                     device_instance=sdc1,
-                                     exists=True)
-        migrate_1 = ActionMigrateFormat(sdc1)
-        migrate_2 = ActionMigrateFormat(sdc1)
-        self.assertEqual(migrate_2.obsoletes(migrate_1), True)
-        self.assertEqual(migrate_1.obsoletes(migrate_2), False)
-
-        # ActionResizeFormat
-        #
-        # - obsoletes other ActionResizeFormat instances w/ lower id and same
-        #   device
-        resize_format_1 = ActionResizeFormat(sdc1, sdc1.size - 1000)
-        resize_format_2 = ActionResizeFormat(sdc1, sdc1.size - 5000)
-        self.assertEqual(resize_format_2.obsoletes(resize_format_1), True)
-        self.assertEqual(resize_format_1.obsoletes(resize_format_2), False)
-
-        # ActionCreateFormat
-        #
-        # - obsoletes migrate, resize format actions w/ lower id on same device
-        new_format = self.newFormat("ext4", mountpoint="/foo", device=sdc1.path)
-        create_format_3 = ActionCreateFormat(sdc1, new_format)
-        self.assertEqual(create_format_3.obsoletes(resize_format_1), True)
-        self.assertEqual(create_format_3.obsoletes(resize_format_2), True)
-        self.assertEqual(create_format_3.obsoletes(migrate_1), True)
-        self.assertEqual(create_format_3.obsoletes(migrate_2), True)
-
-        # ActionResizeDevice
-        #
-        # - obsoletes other ActionResizeDevice instances w/ lower id and same
-        #   device
-        sdc1.exists = True
-        sdc1.format.exists = True
-        resize_device_1 = ActionResizeDevice(sdc1, sdc1.size + 10000)
-        resize_device_2 = ActionResizeDevice(sdc1, sdc1.size - 10000)
-        self.assertEqual(resize_device_2.obsoletes(resize_device_1), True)
-        self.assertEqual(resize_device_1.obsoletes(resize_device_2), False)
-        sdc1.exists = False
-        sdc1.format.exists = False
-
-        # ActionDestroyFormat
-        #
-        # - obsoletes all format actions w/ lower id on same device (including
-        #   self if format does not exist)
-        destroy_format_1 = ActionDestroyFormat(sdc1)
-        self.assertEqual(destroy_format_1.obsoletes(create_format_1), True)
-        self.assertEqual(destroy_format_1.obsoletes(migrate_2), True)
-        self.assertEqual(destroy_format_1.obsoletes(resize_format_1), True)
-        self.assertEqual(destroy_format_1.obsoletes(destroy_format_1), True)
-
-        # ActionDestroyDevice
-        #
-        # - obsoletes all actions w/ lower id that act on the same non-existent
-        #   device (including self)
-        # sdc1 does not exist
-        destroy_sdc1 = ActionDestroyDevice(sdc1)
-        self.assertEqual(destroy_sdc1.obsoletes(create_format_2), True)
-        self.assertEqual(destroy_sdc1.obsoletes(migrate_1), True)
-        self.assertEqual(destroy_sdc1.obsoletes(resize_format_2), True)
-        self.assertEqual(destroy_sdc1.obsoletes(create_device_1), True)
-        self.assertEqual(destroy_sdc1.obsoletes(resize_device_1), True)
-        self.assertEqual(destroy_sdc1.obsoletes(destroy_sdc1), True)
-
-        # ActionDestroyDevice
-        #
-        # - obsoletes all but ActionDestroyFormat actions w/ lower id on the
-        #   same existing device
-        # sda1 exists
-        sda1 = self.storage.devicetree.getDeviceByName("sda1")
-        self.assertNotEqual(sda1, None)
-        resize_sda1_format = ActionResizeFormat(sda1, sda1.size - 50)
-        resize_sda1 = ActionResizeDevice(sda1, sda1.size - 50)
-        destroy_sda1_format = ActionDestroyFormat(sda1)
-        destroy_sda1 = ActionDestroyDevice(sda1)
-        self.assertEqual(destroy_sda1.obsoletes(resize_sda1_format), True)
-        self.assertEqual(destroy_sda1.obsoletes(resize_sda1), True)
-        self.assertEqual(destroy_sda1.obsoletes(destroy_sda1), False)
-        self.assertEqual(destroy_sda1.obsoletes(destroy_sda1_format), False)
-
-    def testActionPruning(self, *args, **kwargs):
-        """ Verify correct functioning of action pruning. """
-        self.destroyAllDevices()
-
-        sda = self.storage.devicetree.getDeviceByName("sda")
-        self.assertNotEqual(sda, None, "failed to find disk 'sda'")
-
-        sda1 = self.newDevice(device_class=PartitionDevice,
-                              name="sda1", size=500, parents=[sda])
-        self.scheduleCreateDevice(device=sda1)
-
-        sda2 = self.newDevice(device_class=PartitionDevice,
-                              name="sda2", size=100000, parents=[sda])
-        self.scheduleCreateDevice(device=sda2)
-        format = self.newFormat("lvmpv", device=sda2.path)
-        self.scheduleCreateFormat(device=sda2, format=format)
-
-        vg = self.newDevice(device_class=LVMVolumeGroupDevice,
-                            name="vg", parents=[sda2])
-        self.scheduleCreateDevice(device=vg)
-
-        lv_root = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_root", vgdev=vg, size=60000)
-        self.scheduleCreateDevice(device=lv_root)
-        format = self.newFormat("ext4", device=lv_root.path, mountpoint="/")
-        self.scheduleCreateFormat(device=lv_root, format=format)
-
-        lv_swap = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_swap", vgdev=vg, size=4000)
-        self.scheduleCreateDevice(device=lv_swap)
-        format = self.newFormat("swap", device=lv_swap.path)
-        self.scheduleCreateFormat(device=lv_swap, format=format)
-
-        # we'll soon schedule destroy actions for these members and the array,
-        # which will test pruning. the whole mess should reduce to nothing
-        sda3 = self.newDevice(device_class=PartitionDevice,
-                              name="sda3", parents=[sda], size=40000)
-        self.scheduleCreateDevice(device=sda3)
-        format = self.newFormat("mdmember", device=sda3.path)
-        self.scheduleCreateFormat(device=sda3, format=format)
-
-        sdb = self.storage.devicetree.getDeviceByName("sdb")
-        self.assertNotEqual(sdb, None, "failed to find disk 'sdb'")
-
-        sdb1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdb1", parents=[sdb], size=40000)
-        self.scheduleCreateDevice(device=sdb1)
-        format = self.newFormat("mdmember", device=sdb1.path,)
-        self.scheduleCreateFormat(device=sdb1, format=format)
-
-        md0 = self.newDevice(device_class=MDRaidArrayDevice,
-                             name="md0", level="raid0", minor=0, size=80000,
-                             memberDevices=2, totalDevices=2,
-                             parents=[sdb1, sda3])
-        self.scheduleCreateDevice(device=md0)
-
-        format = self.newFormat("ext4", device=md0.path, mountpoint="/home")
-        self.scheduleCreateFormat(device=md0, format=format)
-
-        # now destroy the md and its components
-        self.scheduleDestroyFormat(device=md0)
-        self.scheduleDestroyDevice(device=md0)
-        self.scheduleDestroyDevice(device=sdb1)
-        self.scheduleDestroyDevice(device=sda3)
-
-        format = self.newFormat("ext4", mountpoint="/boot", device=sda1.path)
-        self.scheduleCreateFormat(device=sda1, format=format)
-
-        # verify the md actions are present prior to pruning
-        md0_actions = self.storage.devicetree.findActions(devid=md0.id)
-        self.assertNotEqual(len(md0_actions), 0)
-
-        sdb1_actions = self.storage.devicetree.findActions(devid=sdb1.id)
-        self.assertNotEqual(len(sdb1_actions), 0)
-
-        sda3_actions = self.storage.devicetree.findActions(devid=sda3.id)
-        self.assertNotEqual(len(sda3_actions), 0)
-
-        self.storage.devicetree.pruneActions()
-
-        # verify the md actions are gone after pruning
-        md0_actions = self.storage.devicetree.findActions(devid=md0.id)
-        self.assertEqual(len(md0_actions), 0)
-
-        sdb1_actions = self.storage.devicetree.findActions(devid=sdb1.id)
-        self.assertEqual(len(sdb1_actions), 0)
-
-        sda3_actions = self.storage.devicetree.findActions(sda3.id)
-        self.assertEqual(len(sda3_actions), 0)
-
-    def testActionDependencies(self, *args, **kwargs):
-        """ Verify correct functioning of action dependencies. """
-        # ActionResizeDevice
-        # an action that shrinks a device should require the action that
-        # shrinks the device's format
-        lv_root = self.storage.devicetree.getDeviceByName("VolGroup-lv_root")
-        self.assertNotEqual(lv_root, None)
-        shrink_format = ActionResizeFormat(lv_root, lv_root.size - 5000)
-        shrink_device = ActionResizeDevice(lv_root, lv_root.size - 5000)
-        self.assertEqual(shrink_device.requires(shrink_format), True)
-        self.assertEqual(shrink_format.requires(shrink_device), False)
-        shrink_format.cancel()
-        shrink_device.cancel()
-
-        # ActionResizeDevice
-        # an action that grows a format should require the action that
-        # grows the device
-        orig_size = lv_root.currentSize
-        grow_device = ActionResizeDevice(lv_root, orig_size + 100)
-        grow_format = ActionResizeFormat(lv_root, orig_size + 100)
-        self.assertEqual(grow_format.requires(grow_device), True)
-        self.assertEqual(grow_device.requires(grow_format), False)
-
-        # create something like uncommitted autopart
-        self.destroyAllDevices()
-        sda = self.storage.devicetree.getDeviceByName("sda")
-        sdb = self.storage.devicetree.getDeviceByName("sdb")
-        sda1 = self.newDevice(device_class=PartitionDevice,
-                              name="sda1", size=500, parents=[sda])
-        sda1_format = self.newFormat("ext4", mountpoint="/boot",
-                                     device=sda1.path)
-        self.scheduleCreateDevice(device=sda1)
-        self.scheduleCreateFormat(device=sda1, format=sda1_format)
-
-        sda2 = self.newDevice(device_class=PartitionDevice,
-                              name="sda2", size=99500, parents=[sda])
-        sda2_format = self.newFormat("lvmpv", device=sda1.path)
-        self.scheduleCreateDevice(device=sda2)
-        self.scheduleCreateFormat(device=sda2, format=sda2_format)
-
-        sdb1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdb1", size=100000, parents=[sdb])
-        sdb1_format = self.newFormat("lvmpv", device=sdb1.path)
-        self.scheduleCreateDevice(device=sdb1)
-        self.scheduleCreateFormat(device=sdb1, format=sdb1_format)
-
-        vg = self.newDevice(device_class=LVMVolumeGroupDevice,
-                            name="VolGroup", parents=[sda2, sdb1])
-        self.scheduleCreateDevice(device=vg)
-
-        lv_root = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_root", vgdev=vg, size=160000)
-        self.scheduleCreateDevice(device=lv_root)
-        format = self.newFormat("ext4", device=lv_root.path, mountpoint="/")
-        self.scheduleCreateFormat(device=lv_root, format=format)
-
-        lv_swap = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                 name="lv_swap", vgdev=vg, size=4000)
-        self.scheduleCreateDevice(device=lv_swap)
-        format = self.newFormat("swap", device=lv_swap.path)
-        self.scheduleCreateFormat(device=lv_swap, format=format)
-
-        # ActionCreateDevice
-        # creation of an LV should require the actions that create the VG,
-        # its PVs, and the devices that contain the PVs
-        lv_root = self.storage.devicetree.getDeviceByName("VolGroup-lv_root")
-        self.assertNotEqual(lv_root, None)
-        actions = self.storage.devicetree.findActions(type="create",
-                                                      object="device",
-                                                      device=lv_root)
-        self.assertEqual(len(actions), 1,
-                         "wrong number of device create actions for lv_root: "
-                         "%d" % len(actions))
-        create_lv_action = actions[0]
-
-        vgs = [d for d in self.storage.vgs if d.name == "VolGroup"]
-        self.assertNotEqual(vgs, [])
-        vg = vgs[0]
-        actions = self.storage.devicetree.findActions(type="create",
-                                                      object="device",
-                                                      device=vg)
-        self.assertEqual(len(actions), 1,
-                         "wrong number of device create actions for VolGroup")
-        create_vg_action = actions[0]
-
-        self.assertEqual(create_lv_action.requires(create_vg_action), True)
-
-        create_pv_actions = []
-        pvs = [d for d in self.storage.pvs if d in vg.pvs]
-        self.assertNotEqual(pvs, [])
-        for pv in pvs:
-            # include device and format create actions for each pv
-            actions = self.storage.devicetree.findActions(type="create",
-                                                          device=pv)
-            self.assertEqual(len(actions), 2,
-                             "wrong number of device create actions for "
-                             "pv %s" % pv.name)
-            create_pv_actions.append(actions[0])
-
-        for pv_action in create_pv_actions:
-            self.assertEqual(create_lv_action.requires(pv_action), True)
-            # also check that the vg create action requires the pv actions
-            self.assertEqual(create_vg_action.requires(pv_action), True)
-
-        # ActionCreateDevice
-        # the higher numbered partition of two that are scheduled to be
-        # created on a single disk should require the action that creates the
-        # lower numbered of the two, eg: create sda2 before creating sda3
-        sdc = self.storage.devicetree.getDeviceByName("sdc")
-        self.assertNotEqual(sdc, None)
-
-        sdc1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc1", parents=[sdc], size=50000)
-        create_sdc1 = self.scheduleCreateDevice(device=sdc1)
-        self.assertEqual(isinstance(create_sdc1, ActionCreateDevice), True)
-
-        sdc2 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc2", parents=[sdc], size=50000)
-        create_sdc2 = self.scheduleCreateDevice(device=sdc2)
-        self.assertEqual(isinstance(create_sdc2, ActionCreateDevice), True)
-
-        self.assertEqual(create_sdc2.requires(create_sdc1), True)
-        self.assertEqual(create_sdc1.requires(create_sdc2), False)
-
-        # ActionCreateDevice
-        # actions that create partitions on two separate disks should not
-        # require each other, regardless of the partitions' numbers
-        sda1 = self.storage.devicetree.getDeviceByName("sda1")
-        self.assertNotEqual(sda1, None)
-        actions = self.storage.devicetree.findActions(type="create",
-                                                      object="device",
-                                                      device=sda1)
-        self.assertEqual(len(actions), 1,
-                         "wrong number of create actions found for sda1")
-        create_sda1 = actions[0]
-        self.assertEqual(create_sdc2.requires(create_sda1), False)
-        self.assertEqual(create_sda1.requires(create_sdc1), False)
-
-        # ActionDestroyDevice
-        # an action that destroys a device containing an mdmember format
-        # should require the action that destroys the md array it is a
-        # member of if an array is defined
-        self.destroyAllDevices(disks=["sdc", "sdd"])
-        sdc = self.storage.devicetree.getDeviceByName("sdc")
-        self.assertNotEqual(sdc, None)
-        sdd = self.storage.devicetree.getDeviceByName("sdd")
-        self.assertNotEqual(sdd, None)
-
-        sdc1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc1", parents=[sdc], size=40000)
-        self.scheduleCreateDevice(device=sdc1)
-        format = self.newFormat("mdmember", device=sdc1.path)
-        self.scheduleCreateFormat(device=sdc1, format=format)
-
-        sdd1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdd1", parents=[sdd], size=40000)
-        self.scheduleCreateDevice(device=sdd1)
-        format = self.newFormat("mdmember", device=sdd1.path,)
-        self.scheduleCreateFormat(device=sdd1, format=format)
-
-        md0 = self.newDevice(device_class=MDRaidArrayDevice,
-                             name="md0", level="raid0", minor=0, size=80000,
-                             memberDevices=2, totalDevices=2,
-                             parents=[sdc1, sdd1])
-        self.scheduleCreateDevice(device=md0)
-        format = self.newFormat("ext4", device=md0.path, mountpoint="/home")
-        self.scheduleCreateFormat(device=md0, format=format)
-
-        destroy_md0_format = self.scheduleDestroyFormat(device=md0)
-        destroy_md0 = self.scheduleDestroyDevice(device=md0)
-        destroy_members = [self.scheduleDestroyDevice(device=sdc1)]
-        destroy_members.append(self.scheduleDestroyDevice(device=sdd1))
-
-        for member in destroy_members:
-            # device and format destroy actions for md members should require
-            # both device and format destroy actions for the md array
-            for array in [destroy_md0_format, destroy_md0]:
-                self.assertEqual(member.requires(array), True)
-
-        # ActionDestroyDevice
-        # when there are two actions that will each destroy a partition on the
-        # same disk, the action that will destroy the lower-numbered
-        # partition should require the action that will destroy the higher-
-        # numbered partition, eg: destroy sda2 before destroying sda1
-        self.destroyAllDevices(disks=["sdc", "sdd"])
-        sdc1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc1", parents=[sdc], size=50000)
-        self.scheduleCreateDevice(device=sdc1)
-
-        sdc2 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc2", parents=[sdc], size=40000)
-        self.scheduleCreateDevice(device=sdc2)
-
-        destroy_sdc1 = self.scheduleDestroyDevice(device=sdc1)
-        destroy_sdc2 = self.scheduleDestroyDevice(device=sdc2)
-        self.assertEqual(destroy_sdc1.requires(destroy_sdc2), True)
-        self.assertEqual(destroy_sdc2.requires(destroy_sdc1), False)
-
-        self.destroyAllDevices(disks=["sdc", "sdd"])
-        sdc = self.storage.devicetree.getDeviceByName("sdc")
-        self.assertNotEqual(sdc, None)
-        sdd = self.storage.devicetree.getDeviceByName("sdd")
-        self.assertNotEqual(sdd, None)
-
-        sdc1 = self.newDevice(device_class=PartitionDevice,
-                              name="sdc1", parents=[sdc], size=50000)
-        create_pv = self.scheduleCreateDevice(device=sdc1)
-        format = self.newFormat("lvmpv", device=sdc1.path)
-        create_pv_format = self.scheduleCreateFormat(device=sdc1, format=format)
-
-        testvg = self.newDevice(device_class=LVMVolumeGroupDevice,
-                                name="testvg", parents=[sdc1], size=50000)
-        create_vg = self.scheduleCreateDevice(device=testvg)
-        testlv = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                name="testlv", vgdev=testvg, size=30000)
-        create_lv = self.scheduleCreateDevice(device=testlv)
-        format = self.newFormat("ext4", device=testlv.path)
-        create_lv_format = self.scheduleCreateFormat(device=testlv, format=format)
-
-        # ActionCreateFormat
-        # creation of a format on a non-existent device should require the
-        # action that creates the device
-        self.assertEqual(create_lv_format.requires(create_lv), True)
-
-        # ActionCreateFormat
-        # an action that creates a format on a device should require an action
-        # that creates a device that the format's device depends on
-        self.assertEqual(create_lv_format.requires(create_pv), True)
-        self.assertEqual(create_lv_format.requires(create_vg), True)
-
-        # ActionCreateFormat
-        # an action that creates a format on a device should require an action
-        # that creates a format on a device that the format's device depends on
-        self.assertEqual(create_lv_format.requires(create_pv_format), True)
-
-        # XXX from here on, the devices are existing but not in the tree, so
-        #     we instantiate and use actions directly
-        self.destroyAllDevices(disks=["sdc", "sdd"])
-        sdc1 = self.newDevice(device_class=PartitionDevice, exists=True,
-                              name="sdc1", parents=[sdc], size=50000)
-        sdc1.format = self.newFormat("lvmpv", device=sdc1.path, exists=True,
-                                     device_instance=sdc1)
-        testvg = self.newDevice(device_class=LVMVolumeGroupDevice, exists=True,
-                                name="testvg", parents=[sdc1], size=50000)
-        testlv = self.newDevice(device_class=LVMLogicalVolumeDevice,
-                                exists=True,
-                                name="testlv", vgdev=testvg, size=30000)
-        testlv.format = self.newFormat("ext4", device=testlv.path,
-                                       exists=True, device_instance=testlv)
-
-        # ActionResizeDevice
-        # an action that resizes a device should require an action that grows
-        # a device that the first action's device depends on, eg: grow
-        # device containing PV before resize of VG or LVs
-        tmp = sdc1.format
-        sdc1.format = None      # since lvmpv format is not resizable
-        grow_pv = ActionResizeDevice(sdc1, sdc1.size + 10000)
-        grow_lv = ActionResizeDevice(testlv, testlv.size + 5000)
-        grow_lv_format = ActionResizeFormat(testlv, testlv.size + 5000)
-
-        self.assertEqual(grow_lv.requires(grow_pv), True)
-        self.assertEqual(grow_pv.requires(grow_lv), False)
-
-        # ActionResizeFormat
-        # an action that grows a format should require the action that grows
-        # the format's device
-        self.assertEqual(grow_lv_format.requires(grow_lv), True)
-        self.assertEqual(grow_lv.requires(grow_lv_format), False)
-
-        # ActionResizeFormat
-        # an action that resizes a device's format should depend on an action
-        # that grows a device the first device depends on
-        self.assertEqual(grow_lv_format.requires(grow_pv), True)
-        self.assertEqual(grow_pv.requires(grow_lv_format), False)
-
-        # ActionResizeFormat
-        # an action that resizes a device's format should depend on an action
-        # that grows a format on a device the first device depends on
-        # XXX resize of PV format is not allowed, so there's no real-life
-        #     example of this to test
-
-        grow_lv_format.cancel()
-        grow_lv.cancel()
-        grow_pv.cancel()
-
-        # ActionResizeDevice
-        # an action that resizes a device should require an action that grows
-        # a format on a device that the first action's device depends on, eg:
-        # grow PV format before resize of VG or LVs
-        # XXX resize of PV format is not allowed, so there's no real-life
-        #     example of this to test
-
-        # ActionResizeDevice
-        # an action that resizes a device should require an action that
-        # shrinks a device that depends on the first action's device, eg:
-        # shrink LV before resizing VG or PV devices
-        shrink_lv = ActionResizeDevice(testlv, testlv.size - 10000)
-        shrink_pv = ActionResizeDevice(sdc1, sdc1.size - 5000)
-
-        self.assertEqual(shrink_pv.requires(shrink_lv), True)
-        self.assertEqual(shrink_lv.requires(shrink_pv), False)
-
-        # ActionResizeDevice
-        # an action that resizes a device should require an action that
-        # shrinks a format on a device that depends on the first action's
-        # device, eg: shrink LV format before resizing VG or PV devices
-        shrink_lv_format = ActionResizeFormat(testlv, testlv.size)
-        self.assertEqual(shrink_pv.requires(shrink_lv_format), True)
-        self.assertEqual(shrink_lv_format.requires(shrink_pv), False)
-
-        # ActionResizeFormat
-        # an action that resizes a device's format should depend on an action
-        # that shrinks a device that depends on the first device
-        # XXX can't think of a real-world example of this since PVs and MD
-        #     member devices are not resizable in anaconda
-
-        # ActionResizeFormat
-        # an action that resizes a device's format should depend on an action
-        # that shrinks a format on a device that depends on the first device
-        # XXX can't think of a real-world example of this since PVs and MD
-        #     member devices are not resizable in anaconda
-
-        shrink_lv_format.cancel()
-        shrink_lv.cancel()
-        shrink_pv.cancel()
-        sdc1.format = tmp   # restore pv's lvmpv format
-
-        # ActionCreateFormat
-        # an action that creates a format on a device should require an action
-        # that resizes a device that the format's device depends on
-        # XXX Really? Is this always so?
-
-        # ActionCreateFormat
-        # an action that creates a format on a device should require an action
-        # that resizes a format on a device that the format's device depends on
-        # XXX Same as above.
-
-        # ActionCreateFormat
-        # an action that creates a format on a device should require an action
-        # that resizes the device that will contain the format
-        grow_lv = ActionResizeDevice(testlv, testlv.size + 1000)
-        format = self.newFormat("msdos", device=testlv.path)
-        format_lv = ActionCreateFormat(testlv, format)
-        self.assertEqual(format_lv.requires(grow_lv), True)
-        self.assertEqual(grow_lv.requires(format_lv), False)
-
-        # ActionDestroyFormat
-        # an action that destroys a format should require an action that
-        # destroys a device that depends on the format's device
-        destroy_pv_format = ActionDestroyFormat(sdc1)
-        destroy_lv_format = ActionDestroyFormat(testlv)
-        destroy_lv = ActionDestroyDevice(testlv)
-        self.assertEqual(destroy_pv_format.requires(destroy_lv), True)
-        self.assertEqual(destroy_lv.requires(destroy_pv_format), False)
-
-        # ActionDestroyFormat
-        # an action that destroys a format should require an action that
-        # destroys a format on a device that depends on the first format's
-        # device
-        self.assertEqual(destroy_pv_format.requires(destroy_lv_format), True)
-        self.assertEqual(destroy_lv_format.requires(destroy_pv_format), False)
-
-    def testActionSorting(self, *args, **kwargs):
-        """ Verify correct functioning of action sorting. """
-        pass
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(DeviceActionTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
-
diff --git a/tests/storage_test/devicelibs_test/Makefile.am b/tests/storage_test/devicelibs_test/Makefile.am
deleted file mode 100644
index eeeabbd..0000000
--- a/tests/storage_test/devicelibs_test/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# tests/storage/devicelibs/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@redhat.com>
-
-EXTRA_DIST = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/tests/storage_test/devicelibs_test/baseclass.py b/tests/storage_test/devicelibs_test/baseclass.py
deleted file mode 100644
index 06adef9..0000000
--- a/tests/storage_test/devicelibs_test/baseclass.py
+++ /dev/null
@@ -1,80 +0,0 @@
-import unittest
-import os
-import subprocess
-
-
-def makeLoopDev(device_name, file_name):
-    proc = subprocess.Popen(["dd", "if=/dev/zero", "of=%s" % file_name,
-                             "bs=1024", "count=102400"],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    while True:
-        (out, err) = proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            break
-    if rc:
-        raise OSError, "dd failed creating the file %s" % file_name
-
-    proc = subprocess.Popen(["losetup", device_name, file_name],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    while True:
-        (out, err) = proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            break
-    if rc:
-        raise OSError, "losetup failed setting up the loop device %s" % device_name
-
-def removeLoopDev(device_name, file_name):
-    proc = subprocess.Popen(["losetup", "-d", device_name],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    while True:
-        (out, err) = proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            break
-    if rc:
-        raise OSError, "losetup failed removing the loop device %s" % device_name
-
-    os.unlink(file_name)
-
-def getFreeLoopDev():
-    # There's a race condition here where another process could grab the loop
-    # device losetup gives us before we have time to set it up, but that's just
-    # a chance we'll have to take.
-    proc = subprocess.Popen(["losetup", "-f"],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    out = None
-
-    while True:
-        (out, err) = proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            out = out.strip()
-            break
-
-    if rc:
-        raise OSError, "losetup failed to find a free device"
-
-    return out
-
-class DevicelibsTestCase(unittest.TestCase):
-
-    _LOOP_DEVICES = ["/tmp/test-virtdev0", "/tmp/test-virtdev1"]
-
-    def __init__(self, *args, **kwargs):
-        import pyanaconda.anaconda_log
-        pyanaconda.anaconda_log.init()
-
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        self._loopMap = {}
-
-    def setUp(self):
-        for file in self._LOOP_DEVICES:
-            dev = getFreeLoopDev()
-            makeLoopDev(dev, file)
-            self._loopMap[file] = dev
-
-    def tearDown(self):
-        for (file, dev) in self._loopMap.iteritems():
-            removeLoopDev(dev, file)
diff --git a/tests/storage_test/devicelibs_test/crypto_test.py b/tests/storage_test/devicelibs_test/crypto_test.py
deleted file mode 100755
index 3e9e3a6..0000000
--- a/tests/storage_test/devicelibs_test/crypto_test.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-from mock import acceptance
-
-import tempfile
-import os
-
-class CryptoTestCase(baseclass.DevicelibsTestCase):
-
-    def testCrypto(self):
-        _LOOP_DEV0 = self._loopMap[self._LOOP_DEVICES[0]]
-        _LOOP_DEV1 = self._loopMap[self._LOOP_DEVICES[1]]
-
-        import storage.devicelibs.crypto as crypto
-
-
-    @acceptance
-    def testCrypto(self):
-        ##
-        ## is_luks
-        ##
-        # pass
-        self.assertEqual(crypto.is_luks(_LOOP_DEV0), -22)
-        self.assertEqual(crypto.is_luks("/not/existing/device"), -22)
-
-        ##
-        ## luks_format
-        ##
-        # pass
-        self.assertEqual(crypto.luks_format(_LOOP_DEV0, passphrase="secret", cipher="aes-cbc-essiv:sha256", key_size=256), None)
-
-        # make a key file
-        handle, keyfile = tempfile.mkstemp(prefix="key", text=False)
-        os.write(handle, "nobodyknows")
-        os.close(handle)
-
-        # format with key file
-        self.assertEqual(crypto.luks_format(_LOOP_DEV1, key_file=keyfile), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_format, "/not/existing/device", passphrase="secret", cipher="aes-cbc-essiv:sha256", key_size=256)
-        # no passhprase or key file
-        self.assertRaises(ValueError, crypto.luks_format, _LOOP_DEV1, cipher="aes-cbc-essiv:sha256", key_size=256)
-
-        ##
-        ## is_luks
-        ##
-        # pass
-        self.assertEqual(crypto.is_luks(_LOOP_DEV0), 0)    # 0 = is luks
-        self.assertEqual(crypto.is_luks(_LOOP_DEV1), 0)
-
-        ##
-        ## luks_add_key
-        ##
-        # pass
-        self.assertEqual(crypto.luks_add_key(_LOOP_DEV0, new_passphrase="another-secret", passphrase="secret"), None)
-
-        # make another key file
-        handle, new_keyfile = tempfile.mkstemp(prefix="key", text=False)
-        os.write(handle, "area51")
-        os.close(handle)
-
-        # add new key file
-        self.assertEqual(crypto.luks_add_key(_LOOP_DEV1, new_key_file=new_keyfile, key_file=keyfile), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_add_key, _LOOP_DEV0, new_passphrase="another-secret", passphrase="wrong-passphrase")
-
-        ##
-        ## luks_remove_key
-        ##
-        # fail
-        self.assertRaises(RuntimeError, crypto.luks_remove_key, _LOOP_DEV0, del_passphrase="another-secret", passphrase="wrong-pasphrase")
-
-        # pass
-        self.assertEqual(crypto.luks_remove_key(_LOOP_DEV0, del_passphrase="another-secret", passphrase="secret"), None)
-
-        # remove key file
-        self.assertEqual(crypto.luks_remove_key(LOOP_DEV1, del_key_file=new_keyfile, key_file=keyfile), None)
-
-        ##
-        ## luks_open
-        ##
-        # pass
-        self.assertEqual(crypto.luks_open(_LOOP_DEV0, "crypted", passphrase="secret"), None)
-        self.assertEqual(crypto.luks_open(_LOOP_DEV1, "encrypted", key_file=keyfile), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_open, "/not/existing/device", "another-crypted", passphrase="secret")
-        self.assertRaises(crypto.CryptoError, crypto.luks_open, "/not/existing/device", "another-crypted", key_file=keyfile)
-        # no passhprase or key file
-        self.assertRaises(ValueError, crypto.luks_open, _LOOP_DEV1, "another-crypted")
-
-        ##
-        ## luks_status
-        ##
-        # pass
-        self.assertEqual(crypto.luks_status("crypted"), True)
-        self.assertEqual(crypto.luks_status("encrypted"), True)
-        self.assertEqual(crypto.luks_status("another-crypted"), False)
-
-        ##
-        ## luks_uuid
-        ##
-        # pass
-        uuid = crypto.luks_uuid(_LOOP_DEV0)
-        self.assertEqual(crypto.luks_uuid(_LOOP_DEV0), uuid)
-        uuid = crypto.luks_uuid(_LOOP_DEV1)
-        self.assertEqual(crypto.luks_uuid(_LOOP_DEV1), uuid)
-
-        ##
-        ## luks_close
-        ##
-        # pass
-        self.assertEqual(crypto.luks_close("crypted"), None)
-        self.assertEqual(crypto.luks_close("encrypted"), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_close, "wrong-name")
-        # already closed
-        self.assertRaises(crypto.CryptoError, crypto.luks_close, "crypted")
-        self.assertRaises(crypto.CryptoError, crypto.luks_close, "encrypted")
-
-        # cleanup
-        os.unlink(keyfile)
-        os.unlink(new_keyfile)
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(CryptoTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/edd_test.py b/tests/storage_test/devicelibs_test/edd_test.py
deleted file mode 100644
index 4493955..0000000
--- a/tests/storage_test/devicelibs_test/edd_test.py
+++ /dev/null
@@ -1,212 +0,0 @@
-import mock
-
-class EddTestCase(mock.TestCase):
-    def setUp(self):
-        self.setupModules(
-            ['_isys', 'logging', 'pyanaconda.anaconda_log', 'block'])
-
-    def tearDown(self):
-        self.tearDownModules()
-
-    def test_biosdev_to_edd_dir(self):
-        from pyanaconda.storage.devicelibs import edd
-        path = edd.biosdev_to_edd_dir(138)
-        self.assertEqual("/sys/firmware/edd/int13_dev8a", path)
-
-    def test_collect_edd_data(self):
-        from pyanaconda.storage.devicelibs import edd
-
-        # test with vda, vdb
-        fs = EddTestFS(self, edd).vda_vdb()
-        edd_dict = edd.collect_edd_data()
-        self.assertEqual(len(edd_dict), 2)
-        self.assertEqual(edd_dict[0x80].type, "SCSI")
-        self.assertEqual(edd_dict[0x80].scsi_id, 0)
-        self.assertEqual(edd_dict[0x80].scsi_lun, 0)
-        self.assertEqual(edd_dict[0x80].pci_dev, "00:05.0")
-        self.assertEqual(edd_dict[0x80].channel, 0)
-        self.assertEqual(edd_dict[0x80].sectors, 16777216)
-        self.assertEqual(edd_dict[0x81].pci_dev, "00:06.0")
-
-        # test with sda, vda
-        fs = EddTestFS(self, edd).sda_vda()
-        edd_dict = edd.collect_edd_data()
-        self.assertEqual(len(edd_dict), 2)
-        self.assertEqual(edd_dict[0x80].type, "ATA")
-        self.assertEqual(edd_dict[0x80].scsi_id, None)
-        self.assertEqual(edd_dict[0x80].scsi_lun, None)
-        self.assertEqual(edd_dict[0x80].pci_dev, "00:01.1")
-        self.assertEqual(edd_dict[0x80].channel, 0)
-        self.assertEqual(edd_dict[0x80].sectors, 2097152)
-        self.assertEqual(edd_dict[0x80].ata_device, 0)
-        self.assertEqual(edd_dict[0x80].mbr_signature, "0x000ccb01")
-
-    def test_collect_edd_data_cciss(self):
-        from pyanaconda.storage.devicelibs import edd
-        fs = EddTestFS(self, edd).sda_cciss()
-        edd_dict = edd.collect_edd_data()
-
-        self.assertEqual(edd_dict[0x80].pci_dev, None)
-        self.assertEqual(edd_dict[0x80].channel, None)
-
-    def test_edd_entry_str(self):
-        from pyanaconda.storage.devicelibs import edd
-        fs = EddTestFS(self, edd).sda_vda()
-        edd_dict = edd.collect_edd_data()
-        expected_output = """\ttype: ATA, ata_device: 0
-\tchannel: 0, mbr_signature: 0x000ccb01
-\tpci_dev: 00:01.1, scsi_id: None
-\tscsi_lun: None, sectors: 2097152"""
-        self.assertEqual(str(edd_dict[0x80]), expected_output)
-
-    def test_matcher_device_path(self):
-        from pyanaconda.storage.devicelibs import edd
-        fs = EddTestFS(self, edd).sda_vda()
-        edd_dict = edd.collect_edd_data()
-
-        analyzer = edd.EddMatcher(edd_dict[0x80])
-        path = analyzer.devname_from_pci_dev()
-        self.assertEqual(path, "sda")
-
-        analyzer = edd.EddMatcher(edd_dict[0x81])
-        path = analyzer.devname_from_pci_dev()
-        self.assertEqual(path, "vda")
-
-    def test_bad_device_path(self):
-        from pyanaconda.storage.devicelibs import edd
-        fs = EddTestFS(self, edd).sda_vda_no_pcidev()
-        edd_dict = edd.collect_edd_data()
-
-        analyzer = edd.EddMatcher(edd_dict[0x80])
-        path = analyzer.devname_from_pci_dev()
-        self.assertEqual(path, None)
-
-    def test_bad_host_bus(self):
-        from pyanaconda.storage.devicelibs import edd
-        fs = EddTestFS(self, edd).sda_vda_no_host_bus()
-
-        edd_dict = edd.collect_edd_data()
-
-        # 0x80 entry is basted so fail without an exception
-        analyzer = edd.EddMatcher(edd_dict[0x80])
-        devname = analyzer.devname_from_pci_dev()
-        self.assertEqual(devname, None)
-
-        # but still succeed on 0x81
-        analyzer = edd.EddMatcher(edd_dict[0x81])
-        devname = analyzer.devname_from_pci_dev()
-        self.assertEqual(devname, "vda")
-
-    def test_get_edd_dict_1(self):
-        """ Test get_edd_dict()'s pci_dev matching. """
-        from pyanaconda.storage.devicelibs import edd
-        fs = EddTestFS(self, edd).sda_vda()
-        self.assertEqual(edd.get_edd_dict([]),
-                         {'sda' : 0x80,
-                          'vda' : 0x81})
-
-    def test_get_edd_dict_2(self):
-        """ Test get_edd_dict()'s pci_dev matching. """
-        from pyanaconda.storage.devicelibs import edd
-        edd.collect_mbrs = mock.Mock(return_value = {
-                'sda' : '0x000ccb01',
-                'vda' : '0x0006aef1'})
-        fs = EddTestFS(self, edd).sda_vda_missing_details()
-        self.assertEqual(edd.get_edd_dict([]),
-                         {'sda' : 0x80,
-                          'vda' : 0x81})
-
-    def test_get_edd_dict_3(self):
-        """ Test scenario when the 0x80 and 0x81 edd directories contain the
-            same data and give no way to distinguish among the two devices.
-        """
-        from pyanaconda.storage.devicelibs import edd
-        edd.log = mock.Mock()
-        edd.collect_mbrs = mock.Mock(return_value={'sda' : '0x000ccb01',
-                                                   'vda' : '0x0006aef1'})
-        fs = EddTestFS(self, edd).sda_sdb_same()
-        self.assertEqual(edd.get_edd_dict([]), {})
-        self.assertIn((('edd: both edd entries 0x80 and 0x81 seem to map to sda',), {}),
-                      edd.log.info.call_args_list)
-
-class EddTestFS(object):
-    def __init__(self, test_case, target_module):
-        self.fs = mock.DiskIO()
-        test_case.take_over_io(self.fs, target_module)
-
-    def sda_vda_missing_details(self):
-        self.fs["/sys/firmware/edd/int13_dev80"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev80/mbr_signature"] = "0x000ccb01\n"
-        self.fs["/sys/firmware/edd/int13_dev81"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev81/mbr_signature"] = "0x0006aef1\n"
-
-    def sda_vda(self):
-        self.fs["/sys/firmware/edd/int13_dev80"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev80/host_bus"] = "PCI 	00:01.1  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/interface"] = "ATA     	device: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/mbr_signature"] = "0x000ccb01\n"
-        self.fs["/sys/firmware/edd/int13_dev80/sectors"] = "2097152\n"
-
-        self.fs["/sys/firmware/edd/int13_dev81"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev81/host_bus"] = "PCI 	00:05.0  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev81/interface"] = "SCSI    	id: 0  lun: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev81/mbr_signature"] = "0x0006aef1\n"
-        self.fs["/sys/firmware/edd/int13_dev81/sectors"] = "16777216\n"
-
-        self.fs["/sys/devices/pci0000:00/0000:00:01.1/host0/target0:0:0/0:0:0:0/block"] = self.fs.Dir()
-        self.fs["/sys/devices/pci0000:00/0000:00:01.1/host0/target0:0:0/0:0:0:0/block/sda"] = self.fs.Dir()
-
-        self.fs["/sys/devices/pci0000:00/0000:00:05.0/virtio2/block"] = self.fs.Dir()
-        self.fs["/sys/devices/pci0000:00/0000:00:05.0/virtio2/block/vda"] = self.fs.Dir()
-
-        return self.fs
-
-    def sda_vda_no_pcidev(self):
-        self.sda_vda()
-        entries = [e for e in self.fs.fs if e.startswith("/sys/devices/pci")]
-        map(self.fs.os_remove, entries)
-        return self.fs
-
-    def sda_vda_no_host_bus(self):
-        self.sda_vda()
-        self.fs["/sys/firmware/edd/int13_dev80/host_bus"] = "PCI 	00:01.1  channel: \n"
-        self.fs.os_remove("/sys/firmware/edd/int13_dev80/mbr_signature")
-        self.fs.os_remove("/sys/firmware/edd/int13_dev81/mbr_signature")
-
-    def sda_cciss(self):
-        self.fs["/sys/firmware/edd/int13_dev80"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev80/host_bus"] = "PCIX	05:00.0  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/interface"] = "RAID    	identity_tag: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/mbr_signature"] = "0x000ccb01\n"
-        self.fs["/sys/firmware/edd/int13_dev80/sectors"] = "2097152\n"
-
-        return self.fs
-
-    def vda_vdb(self):
-        self.fs["/sys/firmware/edd/int13_dev80"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev80/host_bus"] = "PCI 	00:05.0  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/interface"] = "SCSI    	id: 0  lun: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/sectors"] = "16777216\n"
-
-        self.fs["/sys/firmware/edd/int13_dev81"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev81/host_bus"] = "PCI 	00:06.0  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev81/interface"] = "SCSI    	id: 0  lun: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev81/sectors"] = "4194304\n"
-
-        return self.fs
-
-    def sda_sdb_same(self):
-        self.fs["/sys/firmware/edd/int13_dev80"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev80/host_bus"] = "PCI 	00:01.1  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/interface"] = "ATA     	device: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev80/mbr_signature"] = "0x000ccb01"
-        self.fs["/sys/firmware/edd/int13_dev80/sectors"] = "2097152\n"
-
-        self.fs["/sys/firmware/edd/int13_dev81"] = self.fs.Dir()
-        self.fs["/sys/firmware/edd/int13_dev81/host_bus"] = "PCI 	00:01.1  channel: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev81/interface"] = "ATA     	device: 0\n"
-        self.fs["/sys/firmware/edd/int13_dev81/mbr_signature"] = "0x0006aef1"
-        self.fs["/sys/firmware/edd/int13_dev81/sectors"] = "2097152\n"
-
-        self.fs["/sys/devices/pci0000:00/0000:00:01.1/host0/target0:0:0/0:0:0:0/block"] = self.fs.Dir()
-        self.fs["/sys/devices/pci0000:00/0000:00:01.1/host0/target0:0:0/0:0:0:0/block/sda"] = self.fs.Dir()
diff --git a/tests/storage_test/devicelibs_test/lvm_test.py b/tests/storage_test/devicelibs_test/lvm_test.py
deleted file mode 100755
index e639a21..0000000
--- a/tests/storage_test/devicelibs_test/lvm_test.py
+++ /dev/null
@@ -1,239 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-from mock import acceptance
-
-class LVMTestCase(baseclass.DevicelibsTestCase):
-
-    def testLVM(self):
-        _LOOP_DEV0 = self._loopMap[self._LOOP_DEVICES[0]]
-        _LOOP_DEV1 = self._loopMap[self._LOOP_DEVICES[1]]
-
-        import storage.devicelibs.lvm as lvm
-
-
-    @acceptance
-    def testLVM(self):
-        ##
-        ## pvcreate
-        ##
-        # pass
-        for dev, file in self._loopMap.iteritems():
-            self.assertEqual(lvm.pvcreate(dev), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvcreate, "/not/existing/device")
-
-        ##
-        ## pvresize
-        ##
-        # pass
-        for dev, file in self._loopMap.iteritems():
-            self.assertEqual(lvm.pvresize(dev, 50), None)
-            self.assertEqual(lvm.pvresize(dev, 100), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvresize, "/not/existing/device", 50)
-
-        ##
-        ## vgcreate
-        ##
-        # pass
-        self.assertEqual(lvm.vgcreate("test-vg", [_LOOP_DEV0, _LOOP_DEV1], 4), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgcreate, "another-vg", ["/not/existing/device"], 4)
-        # vg already exists
-        self.assertRaises(lvm.LVMError, lvm.vgcreate, "test-vg", [_LOOP_DEV0], 4)
-        # pe size must be power of 2
-        self.assertRaises(lvm.LVMError, lvm.vgcreate, "another-vg", [_LOOP_DEV0], 5)
-
-        ##
-        ## pvremove
-        ##
-        # fail
-        # cannot remove pv now with vg created
-        self.assertRaises(lvm.LVMError, lvm.pvremove, _LOOP_DEV0)
-
-        ##
-        ## vgdeactivate
-        ##
-        # pass
-        self.assertEqual(lvm.vgdeactivate("test-vg"), None)
-        
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgdeactivate, "wrong-vg-name")
-        
-        ##
-        ## vgreduce
-        ##
-        # pass
-        self.assertEqual(lvm.vgreduce("test-vg", [_LOOP_DEV1]), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgreduce, "wrong-vg-name", [_LOOP_DEV1])
-        self.assertRaises(lvm.LVMError, lvm.vgreduce, "test-vg", ["/not/existing/device"])
-
-        ##
-        ## vgactivate
-        ##
-        # pass
-        self.assertEqual(lvm.vgactivate("test-vg"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgactivate, "wrong-vg-name")
-        
-        ##
-        ## pvinfo
-        ##
-        # pass
-        self.assertEqual(lvm.pvinfo(_LOOP_DEV0)["pv_name"], _LOOP_DEV0)
-        # no vg
-        self.assertEqual(lvm.pvinfo(_LOOP_DEV1)["pv_name"], _LOOP_DEV1)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvinfo, "/not/existing/device")
-
-        ##
-        ## vginfo
-        ##
-        # pass
-        self.assertEqual(lvm.vginfo("test-vg")["pe_size"], "4.00")
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vginfo, "wrong-vg-name")
-
-        ##
-        ## lvcreate
-        ##
-        # pass
-        self.assertEqual(lvm.lvcreate("test-vg", "test-lv", 10), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvcreate, "wrong-vg-name", "another-lv", 10)
-
-        ##
-        ## lvdeactivate
-        ##
-        # pass
-        self.assertEqual(lvm.lvdeactivate("test-vg", "test-lv"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "test-vg", "wrong-lv-name")
-        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "wrong-vg-name", "test-lv")
-        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "wrong-vg-name", "wrong-lv-name")
-
-        ##
-        ## lvresize
-        ##
-        # pass
-        self.assertEqual(lvm.lvresize("test-vg", "test-lv", 60), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "test-vg", "wrong-lv-name", 80)
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "wrong-vg-name", "test-lv", 80)
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "wrong-vg-name", "wrong-lv-name", 80)
-        # changing to same size
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "test-vg", "test-lv", 60)
-
-        ##
-        ## lvactivate
-        ##
-        # pass
-        self.assertEqual(lvm.lvactivate("test-vg", "test-lv"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvactivate, "test-vg", "wrong-lv-name")
-        self.assertRaises(lvm.LVMError, lvm.lvactivate, "wrong-vg-name", "test-lv")
-        self.assertRaises(lvm.LVMError, lvm.lvactivate, "wrong-vg-name", "wrong-lv-name")
-
-        ##
-        ## lvs
-        ##
-        # pass
-        self.assertEqual(lvm.lvs("test-vg")["test-lv"]["size"], "60.00")
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvs, "wrong-vg-name")
-
-        ##
-        ## has_lvm
-        ##
-        # pass
-        self.assertEqual(lvm.has_lvm(), True)
-
-        # fail
-        # TODO
-
-        ##
-        ## lvremove
-        ##
-        # pass
-        self.assertEqual(lvm.lvdeactivate("test-vg", "test-lv"), None)      # is deactivation needed?
-        self.assertEqual(lvm.lvremove("test-vg", "test-lv"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "test-vg", "wrong-lv-name")
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "wrong-vg-name", "test-lv")
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "wrong-vg-name", "wrong-lv-name")
-        # lv already removed
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "test-vg", "test-lv")
-
-        ##
-        ## vgremove
-        ##
-        # pass
-        self.assertEqual(lvm.vgremove("test-vg"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgremove, "wrong-vg-name")
-        # vg already removed
-        self.assertRaises(lvm.LVMError, lvm.vgremove, "test-vg")
-
-        ##
-        ## pvremove
-        ##
-        # pass
-        for dev, file in self._loopMap.iteritems():
-            self.assertEqual(lvm.pvremove(dev), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvremove, "/not/existing/device")
-        # pv already removed
-        self.assertRaises(lvm.LVMError, lvm.pvremove, _LOOP_DEV0)
-
-    #def testGetPossiblePhysicalExtents(self):
-        # pass
-        self.assertEqual(lvm.getPossiblePhysicalExtents(4),
-                         filter(lambda pe: pe > 4, map(lambda power: 2**power, xrange(3, 25))))
-        self.assertEqual(lvm.getPossiblePhysicalExtents(100000),
-                         filter(lambda pe: pe > 100000, map(lambda power: 2**power, xrange(3, 25))))
-
-    #def testGetMaxLVSize(self):
-        # pass
-        self.assertEqual(lvm.getMaxLVSize(), 16*1024**2)
-
-    #def testSafeLVMName(self):
-        # pass
-        self.assertEqual(lvm.safeLvmName("/strange/lv*name5"), "strange_lvname5")
-
-    #def testClampSize(self):
-        # pass
-        self.assertEqual(lvm.clampSize(10, 4), 8L)
-        self.assertEqual(lvm.clampSize(10, 4, True), 12L)
-
-    #def testVGUsedSpace(self):
-        # TODO
-        pass
-
-    #def testVGFreeSpace(self):
-        # TODO
-        pass
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(LVMTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/mdraid_test.py b/tests/storage_test/devicelibs_test/mdraid_test.py
deleted file mode 100755
index 9083bd1..0000000
--- a/tests/storage_test/devicelibs_test/mdraid_test.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-import time
-from mock import acceptance
-
-class MDRaidTestCase(baseclass.DevicelibsTestCase):
-
-    def testMDRaid(self):
-        _LOOP_DEV0 = self._loopMap[self._LOOP_DEVICES[0]]
-        _LOOP_DEV1 = self._loopMap[self._LOOP_DEVICES[1]]
-
-        import storage.devicelibs.mdraid as mdraid
-
-    @acceptance
-    def testMDRaid(self):
-        ##
-        ## getRaidLevels
-        ##
-        # pass
-        self.assertEqual(mdraid.getRaidLevels(), mdraid.getRaidLevels())
-
-        ##
-        ## get_raid_min_members
-        ##
-        # pass
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID0), 2)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID1), 2)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID5), 3)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID6), 4)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID10), 2)
-
-        # fail
-        # unsupported raid
-        self.assertRaises(ValueError, mdraid.get_raid_min_members, 8)
-
-        ##
-        ## get_raid_max_spares
-        ##
-        # pass
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID0, 5), 0)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID1, 5), 3)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID5, 5), 2)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID6, 5), 1)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID10, 5), 3)
-
-        # fail
-        # unsupported raid
-        self.assertRaises(ValueError, mdraid.get_raid_max_spares, 8, 5)
-
-        ##
-        ## mdcreate
-        ##
-        # pass
-        self.assertEqual(mdraid.mdcreate("/dev/md0", 1, [_LOOP_DEV0, _LOOP_DEV1]), None)
-        # wait for raid to settle
-        time.sleep(2)
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mdcreate, "/dev/md1", 1, ["/not/existing/dev0", "/not/existing/dev1"])
-
-        ##
-        ## mddeactivate
-        ##
-        # pass
-        self.assertEqual(mdraid.mddeactivate("/dev/md0"), None)
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mddeactivate, "/not/existing/md")
-
-        ##
-        ## mdadd
-        ##
-        # pass
-        # TODO
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mdadd, "/not/existing/device")
-
-        ##
-        ## mdactivate
-        ##
-        # pass
-        self.assertEqual(mdraid.mdactivate("/dev/md0", [_LOOP_DEV0, _LOOP_DEV1], super_minor=0), None)
-        # wait for raid to settle
-        time.sleep(2)
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mdactivate, "/not/existing/md", super_minor=1)
-        # requires super_minor or uuid
-        self.assertRaises(ValueError, mdraid.mdactivate, "/dev/md1")
-
-        ##
-        ## mddestroy
-        ##
-        # pass
-        # deactivate first
-        self.assertEqual(mdraid.mddeactivate("/dev/md0"), None)
-
-        self.assertEqual(mdraid.mddestroy(_LOOP_DEV0), None)
-        self.assertEqual(mdraid.mddestroy(_LOOP_DEV1), None)
-
-        # fail
-        # not a component
-        self.assertRaises(mdraid.MDRaidError, mdraid.mddestroy, "/dev/md0")
-        self.assertRaises(mdraid.MDRaidError, mdraid.mddestroy, "/not/existing/device")
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(MDRaidTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/mpath_test.py b/tests/storage_test/devicelibs_test/mpath_test.py
deleted file mode 100755
index 5a160d9..0000000
--- a/tests/storage_test/devicelibs_test/mpath_test.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/python
-import mock
-
-class MPathTestCase(mock.TestCase):
-
-    # creating devices, user_friendly_names set to yes
-    output1 = """\
-create: mpathb (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
-size=112G features='0' hwhandler='0' wp=undef
-`-+- policy='round-robin 0' prio=1 status=undef
-  `- 2:0:0:0 sda 8:0  undef ready running
-create: mpatha (36006016092d21800703762872c60db11) undef DGC,RAID 5
-size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
-`-+- policy='round-robin 0' prio=2 status=undef
-  |- 6:0:0:0 sdb 8:16 undef ready running
-  `- 7:0:0:0 sdc 8:32 undef ready running\
-"""
-
-    # listing existing devices, user_friendly_names set to yes
-    output2 = """\
-mpathb (3600a0b800067fcc9000001f34d23ff88) dm-1 IBM,1726-4xx  FAStT
-size=100G features='0' hwhandler='1 rdac' wp=rw
-`-+- policy='round-robin 0' prio=-1 status=active
-  |- 1:0:0:0 sda 8:0  active undef running
-  `- 2:0:0:0 sdc 8:32 active undef running
-mpatha (3600a0b800067fabc000067694d23fe6e) dm-0 IBM,1726-4xx  FAStT
-size=100G features='0' hwhandler='1 rdac' wp=rw
-`-+- policy='round-robin 0' prio=-1 status=active
-  |- 1:0:0:1 sdb 8:16 active undef running
-  `- 2:0:0:1 sdd 8:48 active undef running
-"""
-
-    # creating devices, user_friendly_names set to no
-    output3 = """\
-create: 3600a0b800067fabc000067694d23fe6e undef IBM,1726-4xx  FAStT
-size=100G features='1 queue_if_no_path' hwhandler='1 rdac' wp=undef
-`-+- policy='round-robin 0' prio=6 status=undef
-  |- 1:0:0:1 sdb 8:16 undef ready running
-  `- 2:0:0:1 sdd 8:48 undef ready running
-create: 3600a0b800067fcc9000001f34d23ff88 undef IBM,1726-4xx  FAStT
-size=100G features='1 queue_if_no_path' hwhandler='1 rdac' wp=undef
-`-+- policy='round-robin 0' prio=3 status=undef
-  |- 1:0:0:0 sda 8:0  undef ready running
-  `- 2:0:0:0 sdc 8:32 undef ready running\
-"""
-
-    # listing existing devices, user_friendly_names set to no
-    output4 = """\
-3600a0b800067fcc9000001f34d23ff88 dm-1 IBM,1726-4xx  FAStT
-size=100G features='0' hwhandler='1 rdac' wp=rw
-`-+- policy='round-robin 0' prio=-1 status=active
-  |- 1:0:0:0 sda 8:0  active undef running
-  `- 2:0:0:0 sdc 8:32 active undef running
-3600a0b800067fabc000067694d23fe6e dm-0 IBM,1726-4xx  FAStT
-size=100G features='0' hwhandler='1 rdac' wp=rw
-`-+- policy='round-robin 0' prio=-1 status=active
-  |- 1:0:0:1 sdb 8:16 active undef running
-  `- 2:0:0:1 sdd 8:48 active undef running
-"""
-
-    def setUp(self):
-        self.setupModules(
-            ['_isys', 'logging', 'anaconda_log', 'block'])
-
-    def tearDown(self):
-        self.tearDownModules()
-
-    def testParse(self):
-        from pyanaconda.storage.devicelibs import mpath
-        topology = mpath.parseMultipathOutput(self.output1)
-        self.assertEqual(topology,
-                         {'mpatha':['sdb','sdc'], 'mpathb':['sda']})
-        topology = mpath.parseMultipathOutput(self.output2)
-        self.assertEqual(topology,
-                         {'mpathb':['sda','sdc'], 'mpatha':['sdb', 'sdd']})
-        topology = mpath.parseMultipathOutput(self.output3)
-        self.assertEqual(topology,
-                         {'3600a0b800067fabc000067694d23fe6e' : ['sdb','sdd'],
-                          '3600a0b800067fcc9000001f34d23ff88' : ['sda', 'sdc']})
-        topology = mpath.parseMultipathOutput(self.output4)
-        self.assertEqual(topology,
-                         {'3600a0b800067fabc000067694d23fe6e' : ['sdb','sdd'],
-                          '3600a0b800067fcc9000001f34d23ff88' : ['sda', 'sdc']})
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(MPathTestCase)
diff --git a/tests/storage_test/devicelibs_test/swap_test.py b/tests/storage_test/devicelibs_test/swap_test.py
deleted file mode 100755
index 3808943..0000000
--- a/tests/storage_test/devicelibs_test/swap_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-from mock import acceptance
-
-class SwapTestCase(baseclass.DevicelibsTestCase):
-
-    def testSwap(self):
-        _LOOP_DEV0 = self._loopMap[self._LOOP_DEVICES[0]]
-        _LOOP_DEV1 = self._loopMap[self._LOOP_DEVICES[1]]
-
-        import storage.devicelibs.swap as swap
-
-    @acceptance
-    def testSwap(self):
-        ##
-        ## mkswap
-        ##
-        # pass
-        self.assertEqual(swap.mkswap(_LOOP_DEV0, "swap"), None)
-
-        # fail
-        self.assertRaises(swap.SwapError, swap.mkswap, "/not/existing/device")
-        
-        ##
-        ## swapon
-        ##
-        # pass
-        self.assertEqual(swap.swapon(_LOOP_DEV0, 1), None)
-
-        # fail
-        self.assertRaises(swap.SwapError, swap.swapon, "/not/existing/device")
-        # not a swap partition
-        self.assertRaises(swap.SwapError, swap.swapon, _LOOP_DEV1)
-        
-        # pass
-        # make another swap
-        self.assertEqual(swap.mkswap(_LOOP_DEV1, "another-swap"), None)
-        self.assertEqual(swap.swapon(_LOOP_DEV1), None)
-
-        ##
-        ## swapstatus
-        ##
-        # pass
-        self.assertEqual(swap.swapstatus(_LOOP_DEV0), True)
-        self.assertEqual(swap.swapstatus(_LOOP_DEV1), True)
-        
-        # does not fail
-        self.assertEqual(swap.swapstatus("/not/existing/device"), False)
-
-        ##
-        ## swapoff
-        ##
-        # pass
-        self.assertEqual(swap.swapoff(_LOOP_DEV1), None)
-
-        # check status
-        self.assertEqual(swap.swapstatus(_LOOP_DEV0), True)
-        self.assertEqual(swap.swapstatus(_LOOP_DEV1), False)
-
-        self.assertEqual(swap.swapoff(_LOOP_DEV0), None)
-
-        # fail
-        self.assertRaises(swap.SwapError, swap.swapoff, "/not/existing/device")
-        # already off
-        self.assertRaises(swap.SwapError, swap.swapoff, _LOOP_DEV0)
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(SwapTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/partitioning_test.py b/tests/storage_test/partitioning_test.py
deleted file mode 100644
index 0a8cc75..0000000
--- a/tests/storage_test/partitioning_test.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/python
-
-import unittest
-from mock import Mock
-
-import parted
-
-import pyanaconda.anaconda_log
-pyanaconda.anaconda_log.init()
-
-from pyanaconda.storage.partitioning import getNextPartitionType
-
-# disklabel-type-specific constants
-# keys: disklabel type string
-# values: 3-tuple of (max_primary_count, supports_extended, max_logical_count)
-disklabel_types = {'dos': (4, True, 11),
-                   'gpt': (128, False, 0),
-                   'mac': (62, False, 0)}
-
-class PartitioningTestCase(unittest.TestCase):
-    def getDisk(self, disk_type, primary_count=0,
-                has_extended=False, logical_count=0):
-        """ Return a mock representing a parted.Disk. """
-        disk = Mock()
-
-        disk.type = disk_type
-        label_type_info = disklabel_types[disk_type]
-        (max_primaries, supports_extended, max_logicals) = label_type_info
-        
-        # primary partitions
-        disk.primaryPartitionCount = primary_count
-        disk.maxPrimaryPartitionCount = max_primaries
-
-        # extended partitions
-        disk.supportsFeature = Mock(return_value=supports_extended)
-        disk.getExtendedPartition = Mock(return_value=has_extended)
-
-        # logical partitions
-        disk.getMaxLogicalPartitions = Mock(return_value=max_logicals)
-        disk.getLogicalPartitions = Mock(return_value=[0]*logical_count)
-
-        return disk
-
-    def testNextPartitionType(self):
-        #
-        # DOS
-        #
-        
-        # empty disk, any type
-        disk = self.getDisk(disk_type="dos")
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_NORMAL)
-
-        # three primaries and no extended -> extended
-        disk = self.getDisk(disk_type="dos", primary_count=3)
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_EXTENDED)
-
-        # three primaries and an extended -> primary
-        disk = self.getDisk(disk_type="dos", primary_count=3, has_extended=True)
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_NORMAL)
-
-        # three primaries and an extended w/ no_primary -> logical
-        disk = self.getDisk(disk_type="dos", primary_count=3, has_extended=True)
-        self.assertEqual(getNextPartitionType(disk, no_primary=True),
-                         parted.PARTITION_LOGICAL)
-
-        # four primaries and an extended, available logical -> logical
-        disk = self.getDisk(disk_type="dos", primary_count=4, has_extended=True,
-                            logical_count=9)
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_LOGICAL)
-
-        # four primaries and an extended, no available logical -> None
-        disk = self.getDisk(disk_type="dos", primary_count=4, has_extended=True,
-                            logical_count=11)
-        self.assertEqual(getNextPartitionType(disk), None)
-
-        # four primaries and no extended -> None
-        disk = self.getDisk(disk_type="dos", primary_count=4,
-                            has_extended=False)
-        self.assertEqual(getNextPartitionType(disk), None)
-
-        # free primary slot, extended, no free logical slot -> primary
-        disk = self.getDisk(disk_type="dos", primary_count=3, has_extended=True,
-                            logical_count=11)
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_NORMAL)
-
-        # free primary slot, extended, no free logical slot w/ no_primary
-        # -> None
-        disk = self.getDisk(disk_type="dos", primary_count=3, has_extended=True,
-                            logical_count=11)
-        self.assertEqual(getNextPartitionType(disk, no_primary=True), None)
-
-        #
-        # GPT
-        #
-
-        # empty disk, any partition type
-        disk = self.getDisk(disk_type="gpt")
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_NORMAL)
-
-        # no empty slots -> None
-        disk = self.getDisk(disk_type="gpt", primary_count=128)
-        self.assertEqual(getNextPartitionType(disk), None)
-
-        # no_primary -> None
-        disk = self.getDisk(disk_type="gpt")
-        self.assertEqual(getNextPartitionType(disk, no_primary=True), None)
-
-        #
-        # MAC
-        #
-
-        # empty disk, any partition type
-        disk = self.getDisk(disk_type="mac")
-        self.assertEqual(getNextPartitionType(disk), parted.PARTITION_NORMAL)
-
-        # no empty slots -> None
-        disk = self.getDisk(disk_type="mac", primary_count=62)
-        self.assertEqual(getNextPartitionType(disk), None)
-
-        # no_primary -> None
-        disk = self.getDisk(disk_type="mac")
-        self.assertEqual(getNextPartitionType(disk, no_primary=True), None)
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(PartitioningTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/size_test.py b/tests/storage_test/size_test.py
deleted file mode 100644
index 4f002f2..0000000
--- a/tests/storage_test/size_test.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/python
-#
-# tests/storage/size_tests.py
-# Size test cases for the pyanaconda.storage module
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-# Public License for more details.  You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): David Cantrell <dcantrell@redhat.com>
-
-import unittest
-
-from pyanaconda import anaconda_log
-anaconda_log.init()
-from pyanaconda.storage.errors import *
-from pyanaconda.storage.size import Size, _prefixes
-
-class SizeTestCase(unittest.TestCase):
-    def testExceptions(self):
-        self.assertRaises(SizeParamsError, Size)
-        self.assertRaises(SizeParamsError, Size, bytes=500, spec="45GB")
-
-        self.assertRaises(SizeNotPositiveError, Size, bytes=-1)
-
-        self.assertRaises(SizeNotPositiveError, Size, spec="0")
-        self.assertRaises(SizeNotPositiveError, Size, spec="-1 TB")
-        self.assertRaises(SizeNotPositiveError, Size, spec="-47kb")
-
-        s = Size(bytes=500)
-        self.assertRaises(SizePlacesError, s.humanReadable, places=0)
-
-    def _prefixTestHelper(self, bytes, factor, prefix, abbr):
-        c = bytes * factor
-
-        s = Size(bytes=c)
-        self.assertEquals(s, c)
-
-        if prefix:
-            u = "%sbytes" % prefix
-            s = Size(spec="%ld %s" % (bytes, u))
-            self.assertEquals(s, c)
-            self.assertEquals(s.convertTo(spec=u), bytes)
-
-        if abbr:
-            u = "%sb" % abbr
-            s = Size(spec="%ld %s" % (bytes, u))
-            self.assertEquals(s, c)
-            self.assertEquals(s.convertTo(spec=u), bytes)
-
-        if not prefix and not abbr:
-            s = Size(spec="%ld" % bytes)
-            self.assertEquals(s, c)
-            self.assertEquals(s.convertTo(), bytes)
-
-    def testPrefixes(self):
-        bytes = 47L
-        self._prefixTestHelper(bytes, 1, None, None)
-
-        for factor, prefix, abbr in _prefixes:
-            self._prefixTestHelper(bytes, factor, prefix, abbr)
-
-    def testHumanReadable(self):
-        s = Size(bytes=58929971L)
-        self.assertEquals(s.humanReadable(), "58.9 Mb")
-
-        s = Size(bytes=478360371L)
-        self.assertEquals(s.humanReadable(), "0.48 Gb")
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(SizeTestCase)
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/storagetestcase.py b/tests/storage_test/storagetestcase.py
deleted file mode 100644
index 8e5df1d..0000000
--- a/tests/storage_test/storagetestcase.py
+++ /dev/null
@@ -1,287 +0,0 @@
-#!/usr/bin/python
-
-import unittest
-from mock import Mock
-from mock import TestCase
-
-import parted
-
-import pyanaconda.anaconda_log
-pyanaconda.anaconda_log.init()
-
-import pyanaconda.iutil
-import pyanaconda.storage as storage
-from pyanaconda.storage.formats import getFormat
-
-# device classes for brevity's sake -- later on, that is
-from pyanaconda.storage.devices import StorageDevice
-from pyanaconda.storage.devices import DiskDevice
-from pyanaconda.storage.devices import PartitionDevice
-from pyanaconda.storage.devices import MDRaidArrayDevice
-from pyanaconda.storage.devices import DMDevice
-from pyanaconda.storage.devices import LUKSDevice
-from pyanaconda.storage.devices import LVMVolumeGroupDevice
-from pyanaconda.storage.devices import LVMLogicalVolumeDevice
-from pyanaconda.storage.devices import FileDevice
-
-
-class StorageTestCase(TestCase):
-    """ StorageTestCase
-
-        This is a base class for storage test cases. It sets up imports of
-        the storage package, along with an Anaconda instance and a Storage
-        instance. There are lots of little patches to prevent various pieces
-        of code from trying to access filesystems and/or devices on the host
-        system, along with a couple of convenience methods.
-
-    """
-    def __init__(self, *args, **kwargs):
-        TestCase.__init__(self, *args, **kwargs)
-
-        self.setUpAnaconda()
-
-    def setUpAnaconda(self):
-        pyanaconda.iutil.execWithRedirect = Mock()
-        pyanaconda.iutil.execWithCapture = Mock()
-        pyanaconda.iutil.execWithPulseProgress = Mock()
-        pyanaconda.storage.udev = Mock()
-
-        self.anaconda = Mock()
-        self.setUpStorage()
-
-    def setUpStorage(self):
-        self.setUpDeviceLibs()
-        self.storage = storage.Storage(self.anaconda)
-
-        # device status
-        pyanaconda.storage.devices.StorageDevice.status = False
-        pyanaconda.storage.devices.DMDevice.status = False
-        pyanaconda.storage.devices.LUKSDevice.status = False
-        pyanaconda.storage.devices.LVMVolumeGroupDevice.status = False
-        pyanaconda.storage.devices.MDRaidArrayDevice.status = False
-        pyanaconda.storage.devices.FileDevice.status = False
-
-        # prevent PartitionDevice from trying to dig around in the partition's
-        # geometry
-        pyanaconda.storage.devices.PartitionDevice._setTargetSize = StorageDevice._setTargetSize
-
-        # prevent Ext2FS from trying to run resize2fs to get a filesystem's
-        # minimum size
-        storage.formats.fs.Ext2FS.minSize = storage.formats.DeviceFormat.minSize
-        storage.formats.fs.FS.migratable = storage.formats.DeviceFormat.migratable
-
-    def setUpDeviceLibs(self):
-        # devicelibs shouldn't be touching or looking at the host system
-
-        # lvm is easy because all calls to /sbin/lvm are via lvm()
-        storage.devicelibs.lvm.lvm = Mock()
-
-        # mdraid is easy because all calls to /sbin/mdadm are via mdadm()
-        storage.devicelibs.mdraid.mdadm = Mock()
-
-        # swap
-        storage.devicelibs.swap.swapstatus = Mock(return_value=False)
-        storage.devicelibs.swap.swapon = Mock()
-        storage.devicelibs.swap.swapoff = Mock()
-
-        # dm
-        storage.devicelibs.dm = Mock()
-
-        # crypto/luks
-	storage.devicelibs.crypto.luks_status = Mock(return_value=False)
-	storage.devicelibs.crypto.luks_uuid = Mock()
-	storage.devicelibs.crypto.luks_format = Mock()
-	storage.devicelibs.crypto.luks_open = Mock()
-	storage.devicelibs.crypto.luks_close = Mock()
-	storage.devicelibs.crypto.luks_add_key = Mock()
-	storage.devicelibs.crypto.luks_remove_key = Mock()
-
-        # this list would normally be obtained by parsing /proc/mdstat
-	storage.devicelibs.mdraid.raid_levels = \
-					[storage.devicelibs.mdraid.RAID10,
-					 storage.devicelibs.mdraid.RAID0,
-					 storage.devicelibs.mdraid.RAID1,
-					 storage.devicelibs.mdraid.RAID4,
-					 storage.devicelibs.mdraid.RAID5,
-					 storage.devicelibs.mdraid.RAID6]
-
-    def newDevice(*args, **kwargs):
-        """ Return a new Device instance suitable for testing. """
-        args = args[1:] # drop self arg
-        device_class = kwargs.pop("device_class")
-        exists = kwargs.pop("exists", False)
-        part_type = kwargs.pop("part_type", parted.PARTITION_NORMAL)
-        device = device_class(*args, **kwargs)
-
-        if exists:
-            # set up mock parted.Device w/ correct size
-            device._partedDevice = Mock()
-            device._partedDevice.getSize = Mock(return_value=float(device.size))
-            device._partedDevice.sectorSize = 512
-
-        if isinstance(device, pyanaconda.storage.devices.PartitionDevice):
-            #if exists:
-            #    device.parents = device.req_disks
-            device.parents = device.req_disks
-
-            partedPartition = Mock()
-
-            if device.disk:
-                part_num = device.name[len(device.disk.name):].split("p")[-1]
-                partedPartition.number = int(part_num)
-
-            partedPartition.type = part_type
-            partedPartition.path = device.path
-            partedPartition.getDeviceNodeName = Mock(return_value=device.name)
-            partedPartition.getSize = Mock(return_value=float(device.size))
-            device._partedPartition = partedPartition
-
-        device.exists = exists
-        device.format.exists = exists
-
-        if isinstance(device, pyanaconda.storage.devices.PartitionDevice):
-            # PartitionDevice.probe sets up data needed for resize operations
-            device.probe()
-
-        return device
-
-    def newFormat(*args, **kwargs):
-        """ Return a new DeviceFormat instance suitable for testing.
-
-            Keyword Arguments:
-
-                device_instance - StorageDevice instance this format will be
-                                  created on. This is needed for setup of
-                                  resizable formats.
-
-            All other arguments are passed directly to
-            pyanaconda.storage.formats.getFormat.
-        """
-        args = args[1:] # drop self arg
-        exists = kwargs.pop("exists", False)
-        device_instance = kwargs.pop("device_instance", None)
-        format = getFormat(*args, **kwargs)
-        if isinstance(format, storage.formats.disklabel.DiskLabel):
-            format._partedDevice = Mock()
-            format._partedDisk = Mock()
-
-        format.exists = exists
-
-        if format.resizable and device_instance:
-            format._size = device_instance.currentSize
-
-        return format
-
-    def destroyAllDevices(self, disks=None):
-        """ Remove all devices from the devicetree.
-
-            Keyword Arguments:
-
-                disks - a list of names of disks to remove partitions from
-
-            Note: this is largely ripped off from partitioning.clearPartitions.
-
-        """
-        partitions = self.storage.partitions
-
-        # Sort partitions by descending partition number to minimize confusing
-        # things like multiple "destroy sda5" actions due to parted renumbering
-        # partitions. This can still happen through the UI but it makes sense to
-        # avoid it where possible.
-        partitions.sort(key=lambda p: p.partedPartition.number, reverse=True)
-        for part in partitions:
-            if disks and part.disk.name not in disks:
-                continue
-
-            devices = self.storage.deviceDeps(part)
-            while devices:
-                leaves = [d for d in devices if d.isleaf]
-                for leaf in leaves:
-                    self.storage.destroyDevice(leaf)
-                    devices.remove(leaf)
-
-            self.storage.destroyDevice(part)
-
-    def scheduleCreateDevice(self, *args, **kwargs):
-        """ Schedule an action to create the specified device.
-
-            Verify that the device is not already in the tree and that the
-            act of scheduling/registering the action also adds the device to
-            the tree.
-
-            Return the DeviceAction instance.
-        """
-        device = kwargs.pop("device")
-	if hasattr(device, "req_disks") and \
-	   len(device.req_disks) == 1 and \
-	   not device.parents:
-	    device.parents = device.req_disks
-
-        devicetree = self.storage.devicetree
-
-        self.assertEqual(devicetree.getDeviceByName(device.name), None)
-        action = storage.deviceaction.ActionCreateDevice(device)
-        devicetree.registerAction(action)
-        self.assertEqual(devicetree.getDeviceByName(device.name), device)
-        return action
-
-    def scheduleDestroyDevice(self, *args, **kwargs):
-        """ Schedule an action to destroy the specified device.
-
-            Verify that the device exists initially and that the act of
-            scheduling/registering the action also removes the device from
-            the tree.
-
-            Return the DeviceAction instance.
-        """
-        device = kwargs.pop("device")
-        devicetree = self.storage.devicetree
-
-        self.assertEqual(devicetree.getDeviceByName(device.name), device)
-        action = storage.deviceaction.ActionDestroyDevice(device)
-        devicetree.registerAction(action)
-        self.assertEqual(devicetree.getDeviceByName(device.name), None)
-        return action
-
-    def scheduleCreateFormat(self, *args, **kwargs):
-        """ Schedule an action to write a new format to a device.
-
-            Verify that the device is already in the tree, that it is not
-            already set up to contain the specified format, and that the act
-            of registering/scheduling the action causes the new format to be
-            reflected in the tree.
-
-            Return the DeviceAction instance.
-        """
-        device = kwargs.pop("device")
-        format = kwargs.pop("format")
-        devicetree = self.storage.devicetree
-
-        self.assertNotEqual(device.format, format)
-        self.assertEqual(devicetree.getDeviceByName(device.name), device)
-        action = storage.deviceaction.ActionCreateFormat(device, format)
-        devicetree.registerAction(action)
-        _device = devicetree.getDeviceByName(device.name)
-        self.assertEqual(_device.format, format)
-        return action
-
-    def scheduleDestroyFormat(self, *args, **kwargs):
-        """ Schedule an action to remove a format from a device.
-
-            Verify that the device is already in the tree and that the act
-            of registering/scheduling the action causes the new format to be
-            reflected in the tree.
-
-            Return the DeviceAction instance.
-        """
-        device = kwargs.pop("device")
-        devicetree = self.storage.devicetree
-
-        self.assertEqual(devicetree.getDeviceByName(device.name), device)
-        action = storage.deviceaction.ActionDestroyFormat(device)
-        devicetree.registerAction(action)
-        _device = devicetree.getDeviceByName(device.name)
-        self.assertEqual(_device.format.type, None)
-        return action
-
-
diff --git a/tests/storage_test/tsort_test.py b/tests/storage_test/tsort_test.py
deleted file mode 100644
index cb96997..0000000
--- a/tests/storage_test/tsort_test.py
+++ /dev/null
@@ -1,62 +0,0 @@
-
-import unittest
-import pyanaconda.storage.tsort
-
-class TopologicalSortTestCase(unittest.TestCase):
-    def runTest(self):
-        items = [1, 2, 3, 4, 5]
-        edges = [(5, 4), (4, 3), (3, 2), (2, 1)]
-        graph = pyanaconda.storage.tsort.create_graph(items, edges)
-        self._tsortTest(graph)
-
-        edges = [(5, 4), (2, 3), (1, 5)]
-        graph = pyanaconda.storage.tsort.create_graph(items, edges)
-        self._tsortTest(graph)
-
-        edges = [(5, 4), (4, 3), (3, 2), (2, 1), (3, 5)]
-        graph = pyanaconda.storage.tsort.create_graph(items, edges)
-        self.failUnlessRaises(pyanaconda.storage.tsort.CyclicGraphError,
-                              pyanaconda.storage.tsort.tsort,
-                              graph)
-
-        edges = [(5, 4), (4, 3), (3, 2), (2, 1), (2, 3)]
-        graph = pyanaconda.storage.tsort.create_graph(items, edges)
-        self.failUnlessRaises(pyanaconda.storage.tsort.CyclicGraphError,
-                              pyanaconda.storage.tsort.tsort,
-                              graph)
-
-        items = ['a', 'b', 'c', 'd']
-        edges = [('a', 'c'), ('c', 'b')]
-        graph = pyanaconda.storage.tsort.create_graph(items, edges)
-        self._tsortTest(graph)
-
-    def _tsortTest(self, graph):
-        def check_order(order, graph):
-            # since multiple solutions can potentially exist, just verify
-            # that the ordering constraints are satisfied
-            for parent, child in graph['edges']:
-                if order.index(parent) > order.index(child):
-                    return False
-            return True
-
-        try:
-            order = pyanaconda.storage.tsort.tsort(graph)
-        except Exception as e:
-            self.fail(e)
-
-        # verify output list is of the correct length
-        self.failIf(len(order) != len(graph['items']),
-                    "sorted list length is incorrect")
-
-        # verify that all ordering constraints are satisfied
-        self.failUnless(check_order(order, graph),
-                        "ordering constraints not satisfied")
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(TopologicalSortTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
-
diff --git a/tests/storage_test/udev_test.py b/tests/storage_test/udev_test.py
deleted file mode 100644
index 5d48279..0000000
--- a/tests/storage_test/udev_test.py
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/python
-
-import mock
-import os
-
-class UdevTest(mock.TestCase):
-
-    def setUp(self):
-        self.setupModules(["_isys", "block", "ConfigParser"])
-        self.fs = mock.DiskIO()
-
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.os = mock.Mock()
-        pyanaconda.storage.udev.log = mock.Mock()
-        pyanaconda.storage.udev.open = self.fs.open
-
-    def tearDown(self):
-        self.tearDownModules()
-
-    def udev_enumerate_devices_test(self):
-        import pyanaconda.storage.udev
-        ENUMERATE_LIST = [
-            '/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda',
-            '/sys/devices/virtual/block/loop0',
-            '/sys/devices/virtual/block/loop1',
-            '/sys/devices/virtual/block/ram0',
-            '/sys/devices/virtual/block/ram1',
-            '/sys/devices/virtual/block/dm-0',
-        ]
-
-        pyanaconda.storage.udev.global_udev.enumerate_devices = mock.Mock(return_value=ENUMERATE_LIST)
-        ret = pyanaconda.storage.udev.udev_enumerate_devices()
-        self.assertEqual(set(ret),
-            set(['/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda',
-            '/devices/virtual/block/loop0', '/devices/virtual/block/loop1',
-            '/devices/virtual/block/ram0', '/devices/virtual/block/ram1',
-            '/devices/virtual/block/dm-0'])
-        )
-
-    def udev_get_device_1_test(self):
-        import pyanaconda.storage.udev
-
-        class Device(object):
-            def __init__(self):
-                self.sysname = 'loop1'
-                self.dict = {'symlinks': ['/dev/block/7:1'],
-                    'SUBSYSTEM': 'block',
-                    'MAJOR': '7',
-                    'DEVPATH': '/devices/virtual/block/loop1',
-                    'UDISKS_PRESENTATION_NOPOLICY': '1',
-                    'UDEV_LOG': '3',
-                    'DEVNAME': '/dev/loop1',
-                    'DEVTYPE': 'disk',
-                    'DEVLINKS': '/dev/block/7:1',
-                    'MINOR': '1'
-                }
-
-            def __getitem__(self, key):
-                return self.dict[key]
-
-            def __setitem__(self, key, value):
-                self.dict[key] = value
-
-        pyanaconda.storage.udev.os.path.exists.return_value = True
-        DEV_PATH = '/devices/virtual/block/loop1'
-        dev = Device()
-        pyanaconda.storage.udev.global_udev = mock.Mock()
-        pyanaconda.storage.udev.global_udev.create_device.return_value = dev
-        pyanaconda.storage.udev.udev_parse_uevent_file = mock.Mock(return_value=dev)
-
-        ret = pyanaconda.storage.udev.udev_get_device(DEV_PATH)
-        self.assertTrue(isinstance(ret, Device))
-        self.assertEqual(ret['name'], ret.sysname)
-        self.assertEqual(ret['sysfs_path'], DEV_PATH)
-        self.assertTrue(pyanaconda.storage.udev.udev_parse_uevent_file.called)
-
-    def udev_get_device_2_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.os.path.exists.return_value = False
-        ret = pyanaconda.storage.udev.udev_get_device('')
-        self.assertEqual(ret, None)
-
-    def udev_get_device_3_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.os.path.exists.return_value = True
-        pyanaconda.storage.udev.global_udev = mock.Mock()
-        pyanaconda.storage.udev.global_udev.create_device.return_value = None
-        ret = pyanaconda.storage.udev.udev_get_device('')
-        self.assertEqual(ret, None)
-
-    def udev_get_devices_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.udev_settle = mock.Mock()
-        DEVS = \
-            ['/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda',
-            '/devices/virtual/block/loop0', '/devices/virtual/block/loop1',
-            '/devices/virtual/block/ram0', '/devices/virtual/block/ram1',
-            '/devices/virtual/block/dm-0']
-        pyanaconda.storage.udev.udev_enumerate_devices = mock.Mock(return_value=DEVS)
-        pyanaconda.storage.udev.udev_get_device = lambda x: x
-        ret = pyanaconda.storage.udev.udev_get_devices()
-        self.assertEqual(ret, DEVS)
-
-    def udev_parse_uevent_file_1_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.os.path.normpath = os.path.normpath
-        pyanaconda.storage.udev.os.access.return_value = True
-
-        FILE_CONTENT = "MAJOR=7\nMINOR=1\nDEVNAME=loop1\nDEVTYPE=disk\n"
-        self.fs.open('/sys/devices/virtual/block/loop1/uevent', 'w').write(FILE_CONTENT)
-        dev = {'sysfs_path': '/devices/virtual/block/loop1'}
-        ret = pyanaconda.storage.udev.udev_parse_uevent_file(dev)
-        self.assertEqual(ret,
-            {'sysfs_path': '/devices/virtual/block/loop1',
-            'DEVNAME': 'loop1',
-            'DEVTYPE': 'disk',
-            'MAJOR': '7',
-            'MINOR': '1'})
-
-    def udev_parse_uevent_file_2_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.os.path.normpath = os.path.normpath
-        pyanaconda.storage.udev.os.access.return_value = False
-
-        dev = {'sysfs_path': '/devices/virtual/block/loop1'}
-        ret = pyanaconda.storage.udev.udev_parse_uevent_file(dev)
-        self.assertEqual(ret, {'sysfs_path': '/devices/virtual/block/loop1'})
-
-    def udev_settle_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.util = mock.Mock()
-        pyanaconda.storage.udev.udev_settle()
-        self.assertTrue(pyanaconda.storage.udev.util.run_program.called)
-
-    def udev_trigger_test(self):
-        import pyanaconda.storage.udev
-        pyanaconda.storage.udev.util = mock.Mock()
-        pyanaconda.storage.udev.udev_trigger()
-        self.assertTrue(pyanaconda.storage.udev.util.run_program.called)
-- 
1.7.6.5

