Patchwork [13/35] wic: Remove unused fs_related code

login
register
mail settings
Submitter tom.zanussi@linux.intel.com
Date Aug. 8, 2014, 10:05 p.m.
Message ID <9f732690806db713a38a0d537d1856fc1d5848d4.1407533201.git.tom.zanussi@linux.intel.com>
Download mbox | patch
Permalink /patch/77607/
State Accepted
Commit f0499a07b5641a92993cb878e824ef4cca7911ad
Headers show

Comments

tom.zanussi@linux.intel.com - Aug. 8, 2014, 10:05 p.m.
wic doesn't use it, so remove it.

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
---
 scripts/lib/mic/utils/fs_related.py | 930 ------------------------------------
 1 file changed, 930 deletions(-)

Patch

diff --git a/scripts/lib/mic/utils/fs_related.py b/scripts/lib/mic/utils/fs_related.py
index 182171f..e6e362d 100644
--- a/scripts/lib/mic/utils/fs_related.py
+++ b/scripts/lib/mic/utils/fs_related.py
@@ -31,19 +31,6 @@  from mic.utils import runner
 from mic.utils.errors import *
 from mic.utils.oe.misc import *
 
-def find_binary_inchroot(binary, chroot):
-    paths = ["/usr/sbin",
-             "/usr/bin",
-             "/sbin",
-             "/bin"
-            ]
-
-    for path in paths:
-        bin_path = "%s/%s" % (path, binary)
-        if os.path.exists("%s/%s" % (chroot, bin_path)):
-            return bin_path
-    return None
-
 def find_binary_path(binary):
     if os.environ.has_key("PATH"):
         paths = os.environ["PATH"].split(":")
@@ -72,176 +59,6 @@  def makedirs(dirname):
         if err.errno != errno.EEXIST:
             raise
 
-def mksquashfs(in_img, out_img):
-    fullpathmksquashfs = find_binary_path("mksquashfs")
-    args = [fullpathmksquashfs, in_img, out_img]
-
-    if not sys.stdout.isatty():
-        args.append("-no-progress")
-
-    ret = runner.show(args)
-    if ret != 0:
-        raise SquashfsError("'%s' exited with error (%d)" % (' '.join(args), ret))
-
-def resize2fs(fs, size):
-    resize2fs = find_binary_path("resize2fs")
-    if size == 0:
-        # it means to minimalize it
-        return runner.show([resize2fs, '-M', fs])
-    else:
-        return runner.show([resize2fs, fs, "%sK" % (size / 1024,)])
-
-def my_fuser(fp):
-    fuser = find_binary_path("fuser")
-    if not os.path.exists(fp):
-        return False
-
-    rc = runner.quiet([fuser, "-s", fp])
-    if rc == 0:
-        for pid in runner.outs([fuser, fp]).split():
-            fd = open("/proc/%s/cmdline" % pid, "r")
-            cmdline = fd.read()
-            fd.close()
-            if cmdline[:-1] == "/bin/bash":
-                return True
-
-    # not found
-    return False
-
-class BindChrootMount:
-    """Represents a bind mount of a directory into a chroot."""
-    def __init__(self, src, chroot, dest = None, option = None):
-        self.root = os.path.abspath(os.path.expanduser(chroot))
-        self.option = option
-
-        self.orig_src = self.src = src
-        if os.path.islink(src):
-            self.src = os.readlink(src)
-            if not self.src.startswith('/'):
-                self.src = os.path.abspath(os.path.join(os.path.dirname(src),
-                                                        self.src))
-
-        if not dest:
-            dest = self.src
-        self.dest = os.path.join(self.root, dest.lstrip('/'))
-
-        self.mounted = False
-        self.mountcmd = find_binary_path("mount")
-        self.umountcmd = find_binary_path("umount")
-
-    def ismounted(self):
-        with open('/proc/mounts') as f:
-            for line in f:
-                if line.split()[1] == os.path.abspath(self.dest):
-                    return True
-
-        return False
-
-    def has_chroot_instance(self):
-        lock = os.path.join(self.root, ".chroot.lock")
-        return my_fuser(lock)
-
-    def mount(self):
-        if self.mounted or self.ismounted():
-            return
-
-        makedirs(self.dest)
-        rc = runner.show([self.mountcmd, "--bind", self.src, self.dest])
-        if rc != 0:
-            raise MountError("Bind-mounting '%s' to '%s' failed" %
-                             (self.src, self.dest))
-        if self.option:
-            rc = runner.show([self.mountcmd, "--bind", "-o", "remount,%s" % self.option, self.dest])
-            if rc != 0:
-                raise MountError("Bind-remounting '%s' failed" % self.dest)
-
-        self.mounted = True
-        if os.path.islink(self.orig_src):
-            dest = os.path.join(self.root, self.orig_src.lstrip('/'))
-            if not os.path.exists(dest):
-                os.symlink(self.src, dest)
-
-    def unmount(self):
-        if self.has_chroot_instance():
-            return
-
-        if self.ismounted():
-            runner.show([self.umountcmd, "-l", self.dest])
-        self.mounted = False
-
-class LoopbackMount:
-    """LoopbackMount  compatibility layer for old API"""
-    def __init__(self, lofile, mountdir, fstype = None):
-        self.diskmount = DiskMount(LoopbackDisk(lofile,size = 0),mountdir,fstype,rmmountdir = True)
-        self.losetup = False
-        self.losetupcmd = find_binary_path("losetup")
-
-    def cleanup(self):
-        self.diskmount.cleanup()
-
-    def unmount(self):
-        self.diskmount.unmount()
-
-    def lounsetup(self):
-        if self.losetup:
-            runner.show([self.losetupcmd, "-d", self.loopdev])
-            self.losetup = False
-            self.loopdev = None
-
-    def loopsetup(self):
-        if self.losetup:
-            return
-
-        self.loopdev = get_loop_device(self.losetupcmd, self.lofile)
-        self.losetup = True
-
-    def mount(self):
-        self.diskmount.mount()
-
-class SparseLoopbackMount(LoopbackMount):
-    """SparseLoopbackMount  compatibility layer for old API"""
-    def __init__(self, lofile, mountdir, size, fstype = None):
-        self.diskmount = DiskMount(SparseLoopbackDisk(lofile,size),mountdir,fstype,rmmountdir = True)
-
-    def expand(self, create = False, size = None):
-        self.diskmount.disk.expand(create, size)
-
-    def truncate(self, size = None):
-        self.diskmount.disk.truncate(size)
-
-    def create(self):
-        self.diskmount.disk.create()
-
-class SparseExtLoopbackMount(SparseLoopbackMount):
-    """SparseExtLoopbackMount  compatibility layer for old API"""
-    def __init__(self, lofile, mountdir, size, fstype, blocksize, fslabel):
-        self.diskmount = ExtDiskMount(SparseLoopbackDisk(lofile,size), mountdir, fstype, blocksize, fslabel, rmmountdir = True)
-
-
-    def __format_filesystem(self):
-        self.diskmount.__format_filesystem()
-
-    def create(self):
-        self.diskmount.disk.create()
-
-    def resize(self, size = None):
-        return self.diskmount.__resize_filesystem(size)
-
-    def mount(self):
-        self.diskmount.mount()
-
-    def __fsck(self):
-        self.extdiskmount.__fsck()
-
-    def __get_size_from_filesystem(self):
-        return self.diskmount.__get_size_from_filesystem()
-
-    def __resize_to_minimal(self):
-        return self.diskmount.__resize_to_minimal()
-
-    def resparse(self, size = None):
-        return self.diskmount.resparse(size)
-
 class Disk:
     """Generic base object for a disk
 
@@ -270,20 +87,6 @@  class Disk:
     size = property(get_size)
 
 
-class RawDisk(Disk):
-    """A Disk backed by a block device.
-    Note that create() is a no-op.
-    """
-    def __init__(self, size, device):
-        Disk.__init__(self, size, device)
-
-    def fixed(self):
-        return True
-
-    def exists(self):
-        return True
-
-
 class DiskImage(Disk):
     """
     A Disk backed by a file.
@@ -311,76 +114,6 @@  class DiskImage(Disk):
         self.device = self.image_file
 
 
-class LoopbackDisk(Disk):
-    """A Disk backed by a file via the loop module."""
-    def __init__(self, lofile, size):
-        Disk.__init__(self, size)
-        self.lofile = lofile
-        self.losetupcmd = find_binary_path("losetup")
-
-    def fixed(self):
-        return False
-
-    def exists(self):
-        return os.path.exists(self.lofile)
-
-    def create(self):
-        if self.device is not None:
-            return
-
-        self.device = get_loop_device(self.losetupcmd, self.lofile)
-
-    def cleanup(self):
-        if self.device is None:
-            return
-        msger.debug("Losetup remove %s" % self.device)
-        rc = runner.show([self.losetupcmd, "-d", self.device])
-        self.device = None
-
-class SparseLoopbackDisk(LoopbackDisk):
-    """A Disk backed by a sparse file via the loop module."""
-    def __init__(self, lofile, size):
-        LoopbackDisk.__init__(self, lofile, size)
-
-    def expand(self, create = False, size = None):
-        flags = os.O_WRONLY
-        if create:
-            flags |= os.O_CREAT
-            if not os.path.exists(self.lofile):
-                makedirs(os.path.dirname(self.lofile))
-
-        if size is None:
-            size = self.size
-
-        msger.debug("Extending sparse file %s to %d" % (self.lofile, size))
-        if create:
-            fd = os.open(self.lofile, flags, 0644)
-        else:
-            fd = os.open(self.lofile, flags)
-
-        if size <= 0:
-            size = 1
-        try:
-            os.ftruncate(fd, size)
-        except:
-            # may be limited by 2G in 32bit env
-            os.ftruncate(fd, 2**31L)
-
-        os.close(fd)
-
-    def truncate(self, size = None):
-        if size is None:
-            size = self.size
-
-        msger.debug("Truncating sparse file %s to %d" % (self.lofile, size))
-        fd = os.open(self.lofile, os.O_WRONLY)
-        os.ftruncate(fd, size)
-        os.close(fd)
-
-    def create(self):
-        self.expand(create = True)
-        LoopbackDisk.create(self)
-
 class Mount:
     """A generic base class to deal with mounting things."""
     def __init__(self, mountdir):
@@ -395,666 +128,3 @@  class Mount:
     def unmount(self):
         pass
 
-class DiskMount(Mount):
-    """A Mount object that handles mounting of a Disk."""
-    def __init__(self, disk, mountdir, fstype = None, rmmountdir = True):
-        Mount.__init__(self, mountdir)
-
-        self.disk = disk
-        self.fstype = fstype
-        self.rmmountdir = rmmountdir
-
-        self.mounted = False
-        self.rmdir   = False
-        if fstype:
-            self.mkfscmd = find_binary_path("mkfs." + self.fstype)
-        else:
-            self.mkfscmd = None
-        self.mountcmd = find_binary_path("mount")
-        self.umountcmd = find_binary_path("umount")
-
-    def cleanup(self):
-        Mount.cleanup(self)
-        self.disk.cleanup()
-
-    def unmount(self):
-        if self.mounted:
-            msger.debug("Unmounting directory %s" % self.mountdir)
-            runner.quiet('sync') # sync the data on this mount point
-            rc = runner.show([self.umountcmd, "-l", self.mountdir])
-            if rc == 0:
-                self.mounted = False
-            else:
-                raise MountError("Failed to umount %s" % self.mountdir)
-        if self.rmdir and not self.mounted:
-            try:
-                os.rmdir(self.mountdir)
-            except OSError, e:
-                pass
-            self.rmdir = False
-
-
-    def __create(self):
-        self.disk.create()
-
-
-    def mount(self, options = None):
-        if self.mounted:
-            return
-
-        if not os.path.isdir(self.mountdir):
-            msger.debug("Creating mount point %s" % self.mountdir)
-            os.makedirs(self.mountdir)
-            self.rmdir = self.rmmountdir
-
-        self.__create()
-
-        msger.debug("Mounting %s at %s" % (self.disk.device, self.mountdir))
-        if options:
-            args = [ self.mountcmd, "-o", options, self.disk.device, self.mountdir ]
-        else:
-            args = [ self.mountcmd, self.disk.device, self.mountdir ]
-        if self.fstype:
-            args.extend(["-t", self.fstype])
-
-        rc = runner.show(args)
-        if rc != 0:
-            raise MountError("Failed to mount '%s' to '%s' with command '%s'. Retval: %s" %
-                             (self.disk.device, self.mountdir, " ".join(args), rc))
-
-        self.mounted = True
-
-class ExtDiskMount(DiskMount):
-    """A DiskMount object that is able to format/resize ext[23] filesystems."""
-    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None):
-        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
-        self.blocksize = blocksize
-        self.fslabel = fslabel.replace("/", "")
-        self.uuid = str(uuid.uuid4())
-        self.skipformat = skipformat
-        self.fsopts = fsopts
-        self.extopts = None
-        self.dumpe2fs = find_binary_path("dumpe2fs")
-        self.tune2fs = find_binary_path("tune2fs")
-
-    def __parse_field(self, output, field):
-        for line in output.split("\n"):
-            if line.startswith(field + ":"):
-                return line[len(field) + 1:].strip()
-
-        raise KeyError("Failed to find field '%s' in output" % field)
-
-    def __format_filesystem(self):
-        if self.skipformat:
-            msger.debug("Skip filesystem format.")
-            return
-
-        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b",
-                   str(self.blocksize), "-U", self.uuid]
-        if self.extopts:
-            cmdlist.extend(self.extopts.split())
-        cmdlist.extend([self.disk.device])
-
-        rc, errout = runner.runtool(cmdlist, catch=2)
-        if rc != 0:
-            raise MountError("Error creating %s filesystem on disk %s:\n%s" %
-                             (self.fstype, self.disk.device, errout))
-
-        if not self.extopts:
-            msger.debug("Tuning filesystem on %s" % self.disk.device)
-            runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
-
-    def __resize_filesystem(self, size = None):
-        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
-
-        if size is None:
-            size = self.disk.size
-
-        if size == current_size:
-            return
-
-        if size > current_size:
-            self.disk.expand(size)
-
-        self.__fsck()
-
-        resize2fs(self.disk.lofile, size)
-        return size
-
-    def __create(self):
-        resize = False
-        if not self.disk.fixed() and self.disk.exists():
-            resize = True
-
-        self.disk.create()
-
-        if resize:
-            self.__resize_filesystem()
-        else:
-            self.__format_filesystem()
-
-    def mount(self, options = None):
-        self.__create()
-        DiskMount.mount(self, options)
-
-    def __fsck(self):
-        msger.info("Checking filesystem %s" % self.disk.lofile)
-        runner.quiet(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
-
-    def __get_size_from_filesystem(self):
-        return int(self.__parse_field(runner.outs([self.dumpe2fs, '-h', self.disk.lofile]),
-                                      "Block count")) * self.blocksize
-
-    def __resize_to_minimal(self):
-        self.__fsck()
-
-        #
-        # Use a binary search to find the minimal size
-        # we can resize the image to
-        #
-        bot = 0
-        top = self.__get_size_from_filesystem()
-        while top != (bot + 1):
-            t = bot + ((top - bot) / 2)
-
-            if not resize2fs(self.disk.lofile, t):
-                top = t
-            else:
-                bot = t
-        return top
-
-    def resparse(self, size = None):
-        self.cleanup()
-        if size == 0:
-            minsize = 0
-        else:
-            minsize = self.__resize_to_minimal()
-            self.disk.truncate(minsize)
-
-        self.__resize_filesystem(size)
-        return minsize
-
-class VfatDiskMount(DiskMount):
-    """A DiskMount object that is able to format vfat/msdos filesystems."""
-    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None):
-        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
-        self.blocksize = blocksize
-        self.fslabel = fslabel.replace("/", "")
-        rand1 = random.randint(0, 2**16 - 1)
-        rand2 = random.randint(0, 2**16 - 1)
-        self.uuid = "%04X-%04X" % (rand1, rand2)
-        self.skipformat = skipformat
-        self.fsopts = fsopts
-        self.fsckcmd = find_binary_path("fsck." + self.fstype)
-
-    def __format_filesystem(self):
-        if self.skipformat:
-            msger.debug("Skip filesystem format.")
-            return
-
-        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        rc = runner.show([self.mkfscmd, "-n", self.fslabel,
-                          "-i", self.uuid.replace("-", ""), self.disk.device])
-        if rc != 0:
-            raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
-
-        msger.verbose("Tuning filesystem on %s" % self.disk.device)
-
-    def __resize_filesystem(self, size = None):
-        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
-
-        if size is None:
-            size = self.disk.size
-
-        if size == current_size:
-            return
-
-        if size > current_size:
-            self.disk.expand(size)
-
-        self.__fsck()
-
-        #resize2fs(self.disk.lofile, size)
-        return size
-
-    def __create(self):
-        resize = False
-        if not self.disk.fixed() and self.disk.exists():
-            resize = True
-
-        self.disk.create()
-
-        if resize:
-            self.__resize_filesystem()
-        else:
-            self.__format_filesystem()
-
-    def mount(self, options = None):
-        self.__create()
-        DiskMount.mount(self, options)
-
-    def __fsck(self):
-        msger.debug("Checking filesystem %s" % self.disk.lofile)
-        runner.show([self.fsckcmd, "-y", self.disk.lofile])
-
-    def __get_size_from_filesystem(self):
-        return self.disk.size
-
-    def __resize_to_minimal(self):
-        self.__fsck()
-
-        #
-        # Use a binary search to find the minimal size
-        # we can resize the image to
-        #
-        bot = 0
-        top = self.__get_size_from_filesystem()
-        return top
-
-    def resparse(self, size = None):
-        self.cleanup()
-        minsize = self.__resize_to_minimal()
-        self.disk.truncate(minsize)
-        self.__resize_filesystem(size)
-        return minsize
-
-class BtrfsDiskMount(DiskMount):
-    """A DiskMount object that is able to format/resize btrfs filesystems."""
-    def __init__(self, disk, mountdir, fstype, blocksize, fslabel, rmmountdir=True, skipformat = False, fsopts = None):
-        self.__check_btrfs()
-        DiskMount.__init__(self, disk, mountdir, fstype, rmmountdir)
-        self.blocksize = blocksize
-        self.fslabel = fslabel.replace("/", "")
-        self.uuid  = None
-        self.skipformat = skipformat
-        self.fsopts = fsopts
-        self.blkidcmd = find_binary_path("blkid")
-        self.btrfsckcmd = find_binary_path("btrfsck")
-
-    def __check_btrfs(self):
-        found = False
-        """ Need to load btrfs module to mount it """
-        load_module("btrfs")
-        for line in open("/proc/filesystems").xreadlines():
-            if line.find("btrfs") > -1:
-                found = True
-                break
-        if not found:
-            raise MountError("Your system can't mount btrfs filesystem, please make sure your kernel has btrfs support and the module btrfs.ko has been loaded.")
-
-        # disable selinux, selinux will block write
-        if os.path.exists("/usr/sbin/setenforce"):
-            runner.show(["/usr/sbin/setenforce", "0"])
-
-    def __parse_field(self, output, field):
-        for line in output.split(" "):
-            if line.startswith(field + "="):
-                return line[len(field) + 1:].strip().replace("\"", "")
-
-        raise KeyError("Failed to find field '%s' in output" % field)
-
-    def __format_filesystem(self):
-        if self.skipformat:
-            msger.debug("Skip filesystem format.")
-            return
-
-        msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device))
-        rc = runner.show([self.mkfscmd, "-L", self.fslabel, self.disk.device])
-        if rc != 0:
-            raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device))
-
-        self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
-
-    def __resize_filesystem(self, size = None):
-        current_size = os.stat(self.disk.lofile)[stat.ST_SIZE]
-
-        if size is None:
-            size = self.disk.size
-
-        if size == current_size:
-            return
-
-        if size > current_size:
-            self.disk.expand(size)
-
-        self.__fsck()
-        return size
-
-    def __create(self):
-        resize = False
-        if not self.disk.fixed() and self.disk.exists():
-            resize = True
-
-        self.disk.create()
-
-        if resize:
-            self.__resize_filesystem()
-        else:
-            self.__format_filesystem()
-
-    def mount(self, options = None):
-        self.__create()
-        DiskMount.mount(self, options)
-
-    def __fsck(self):
-        msger.debug("Checking filesystem %s" % self.disk.lofile)
-        runner.quiet([self.btrfsckcmd, self.disk.lofile])
-
-    def __get_size_from_filesystem(self):
-        return self.disk.size
-
-    def __resize_to_minimal(self):
-        self.__fsck()
-
-        return self.__get_size_from_filesystem()
-
-    def resparse(self, size = None):
-        self.cleanup()
-        minsize = self.__resize_to_minimal()
-        self.disk.truncate(minsize)
-        self.__resize_filesystem(size)
-        return minsize
-
-class DeviceMapperSnapshot(object):
-    def __init__(self, imgloop, cowloop):
-        self.imgloop = imgloop
-        self.cowloop = cowloop
-
-        self.__created = False
-        self.__name = None
-        self.dmsetupcmd = find_binary_path("dmsetup")
-
-        """Load dm_snapshot if it isn't loaded"""
-        load_module("dm_snapshot")
-
-    def get_path(self):
-        if self.__name is None:
-            return None
-        return os.path.join("/dev/mapper", self.__name)
-    path = property(get_path)
-
-    def create(self):
-        if self.__created:
-            return
-
-        self.imgloop.create()
-        self.cowloop.create()
-
-        self.__name = "imgcreate-%d-%d" % (os.getpid(),
-                                           random.randint(0, 2**16))
-
-        size = os.stat(self.imgloop.lofile)[stat.ST_SIZE]
-
-        table = "0 %d snapshot %s %s p 8" % (size / 512,
-                                             self.imgloop.device,
-                                             self.cowloop.device)
-
-        args = [self.dmsetupcmd, "create", self.__name, "--table", table]
-        if runner.show(args) != 0:
-            self.cowloop.cleanup()
-            self.imgloop.cleanup()
-            raise SnapshotError("Could not create snapshot device using: " + ' '.join(args))
-
-        self.__created = True
-
-    def remove(self, ignore_errors = False):
-        if not self.__created:
-            return
-
-        time.sleep(2)
-        rc = runner.show([self.dmsetupcmd, "remove", self.__name])
-        if not ignore_errors and rc != 0:
-            raise SnapshotError("Could not remove snapshot device")
-
-        self.__name = None
-        self.__created = False
-
-        self.cowloop.cleanup()
-        self.imgloop.cleanup()
-
-    def get_cow_used(self):
-        if not self.__created:
-            return 0
-
-        #
-        # dmsetup status on a snapshot returns e.g.
-        #   "0 8388608 snapshot 416/1048576"
-        # or, more generally:
-        #   "A B snapshot C/D"
-        # where C is the number of 512 byte sectors in use
-        #
-        out = runner.outs([self.dmsetupcmd, "status", self.__name])
-        try:
-            return int((out.split()[3]).split('/')[0]) * 512
-        except ValueError:
-            raise SnapshotError("Failed to parse dmsetup status: " + out)
-
-def create_image_minimizer(path, image, minimal_size):
-    """
-    Builds a copy-on-write image which can be used to
-    create a device-mapper snapshot of an image where
-    the image's filesystem is as small as possible
-
-    The steps taken are:
-      1) Create a sparse COW
-      2) Loopback mount the image and the COW
-      3) Create a device-mapper snapshot of the image
-         using the COW
-      4) Resize the filesystem to the minimal size
-      5) Determine the amount of space used in the COW
-      6) Restroy the device-mapper snapshot
-      7) Truncate the COW, removing unused space
-      8) Create a squashfs of the COW
-    """
-    imgloop = LoopbackDisk(image, None) # Passing bogus size - doesn't matter
-
-    cowloop = SparseLoopbackDisk(os.path.join(os.path.dirname(path), "osmin"),
-                                 64L * 1024L * 1024L)
-
-    snapshot = DeviceMapperSnapshot(imgloop, cowloop)
-
-    try:
-        snapshot.create()
-
-        resize2fs(snapshot.path, minimal_size)
-
-        cow_used = snapshot.get_cow_used()
-    finally:
-        snapshot.remove(ignore_errors = (not sys.exc_info()[0] is None))
-
-    cowloop.truncate(cow_used)
-
-    mksquashfs(cowloop.lofile, path)
-
-    os.unlink(cowloop.lofile)
-
-def load_module(module):
-    found = False
-    for line in open('/proc/modules').xreadlines():
-        if line.startswith("%s " % module):
-            found = True
-            break
-    if not found:
-        msger.info("Loading %s..." % module)
-        runner.quiet(['modprobe', module])
-
-class LoopDevice(object):
-    def __init__(self, loopid=None):
-        self.device = None
-        self.loopid = loopid
-        self.created = False
-        self.kpartxcmd = find_binary_path("kpartx")
-        self.losetupcmd = find_binary_path("losetup")
-
-    def register(self, device):
-        self.device = device
-        self.loopid = None
-        self.created = True
-
-    def reg_atexit(self):
-        import atexit
-        atexit.register(self.close)
-
-    def _genloopid(self):
-        import glob
-        if not glob.glob("/dev/loop[0-9]*"):
-            return 10
-
-        fint = lambda x: x[9:].isdigit() and int(x[9:]) or 0
-        maxid = 1 + max(filter(lambda x: x<100,
-                               map(fint, glob.glob("/dev/loop[0-9]*"))))
-        if maxid < 10: maxid = 10
-        if maxid >= 100: raise
-        return maxid
-
-    def _kpseek(self, device):
-        rc, out = runner.runtool([self.kpartxcmd, '-l', '-v', device])
-        if rc != 0:
-            raise MountError("Can't query dm snapshot on %s" % device)
-        for line in out.splitlines():
-            if line and line.startswith("loop"):
-                return True
-        return False
-
-    def _loseek(self, device):
-        import re
-        rc, out = runner.runtool([self.losetupcmd, '-a'])
-        if rc != 0:
-            raise MountError("Failed to run 'losetup -a'")
-        for line in out.splitlines():
-            m = re.match("([^:]+): .*", line)
-            if m and m.group(1) == device:
-                return True
-        return False
-
-    def create(self):
-        if not self.created:
-            if not self.loopid:
-                self.loopid = self._genloopid()
-            self.device = "/dev/loop%d" % self.loopid
-            if os.path.exists(self.device):
-                if self._loseek(self.device):
-                    raise MountError("Device busy: %s" % self.device)
-                else:
-                    self.created = True
-                    return
-
-            mknod = find_binary_path('mknod')
-            rc = runner.show([mknod, '-m664', self.device, 'b', '7', str(self.loopid)])
-            if rc != 0:
-                raise MountError("Failed to create device %s" % self.device)
-            else:
-                self.created = True
-
-    def close(self):
-        if self.created:
-            try:
-                self.cleanup()
-                self.device = None
-            except MountError, e:
-                msger.error("%s" % e)
-
-    def cleanup(self):
-
-        if self.device is None:
-            return
-
-
-        if self._kpseek(self.device):
-            if self.created:
-                for i in range(3, os.sysconf("SC_OPEN_MAX")):
-                    try:
-                        os.close(i)
-                    except:
-                        pass
-            runner.quiet([self.kpartxcmd, "-d", self.device])
-        if self._loseek(self.device):
-            runner.quiet([self.losetupcmd, "-d", self.device])
-        # FIXME: should sleep a while between two loseek
-        if self._loseek(self.device):
-            msger.warning("Can't cleanup loop device %s" % self.device)
-        elif self.loopid:
-            os.unlink(self.device)
-
-DEVICE_PIDFILE_DIR = "/var/tmp/mic/device"
-DEVICE_LOCKFILE = "/var/lock/__mic_loopdev.lock"
-
-def get_loop_device(losetupcmd, lofile):
-    global DEVICE_PIDFILE_DIR
-    global DEVICE_LOCKFILE
-
-    import fcntl
-    makedirs(os.path.dirname(DEVICE_LOCKFILE))
-    fp = open(DEVICE_LOCKFILE, 'w')
-    fcntl.flock(fp, fcntl.LOCK_EX)
-    try:
-        loopdev = None
-        devinst = LoopDevice()
-
-        # clean up left loop device first
-        clean_loop_devices()
-
-        # provide an avaible loop device
-        rc, out = runner.runtool([losetupcmd, "--find"])
-        if rc == 0:
-            loopdev = out.split()[0]
-            devinst.register(loopdev)
-        if not loopdev or not os.path.exists(loopdev):
-            devinst.create()
-            loopdev = devinst.device
-
-        # setup a loop device for image file
-        rc = runner.show([losetupcmd, loopdev, lofile])
-        if rc != 0:
-            raise MountError("Failed to setup loop device for '%s'" % lofile)
-
-        devinst.reg_atexit()
-
-        # try to save device and pid
-        makedirs(DEVICE_PIDFILE_DIR)
-        pidfile = os.path.join(DEVICE_PIDFILE_DIR, os.path.basename(loopdev))
-        if os.path.exists(pidfile):
-            os.unlink(pidfile)
-        with open(pidfile, 'w') as wf:
-            wf.write(str(os.getpid()))
-
-    except MountError, err:
-        raise CreatorError("%s" % str(err))
-    except:
-        raise
-    finally:
-        try:
-            fcntl.flock(fp, fcntl.LOCK_UN)
-            fp.close()
-            os.unlink(DEVICE_LOCKFILE)
-        except:
-            pass
-
-    return loopdev
-
-def clean_loop_devices(piddir=DEVICE_PIDFILE_DIR):
-    if not os.path.exists(piddir) or not os.path.isdir(piddir):
-        return
-
-    for loopdev in os.listdir(piddir):
-        pidfile = os.path.join(piddir, loopdev)
-        try:
-            with open(pidfile, 'r') as rf:
-                devpid = int(rf.read())
-        except:
-            devpid = None
-
-        # if the process using this device is alive, skip it
-        if not devpid or os.path.exists(os.path.join('/proc', str(devpid))):
-            continue
-
-        # try to clean it up
-        try:
-            devinst = LoopDevice()
-            devinst.register(os.path.join('/dev', loopdev))
-            devinst.cleanup()
-            os.unlink(pidfile)
-        except:
-            pass
-