[et-mgmt-tools] [PATCH] Add vdisk support

john.levon at sun.com john.levon at sun.com
Thu Dec 4 04:31:48 UTC 2008


# HG changeset patch
# User john.levon at sun.com
# Date 1228365031 28800
# Node ID 152e0bfb277efb24679d7c7f440df0b0f6b21529
# Parent  35baacfe79834400949ebdba69f952ed873ae442
Add vdisk support

Add support for the vdisk format used in Solaris.

Signed-off-by: John Levon <john.levon at sun.com>

diff --git a/virt-install b/virt-install
--- a/virt-install
+++ b/virt-install
@@ -189,9 +189,13 @@ def get_disk(disk, size, sparse, guest, 
                                  readOnly=readOnly, device=device, bus=bus,
                                  conn=guest.conn)
         # Default file backed PV guests to tap driver
-        if d.type == virtinst.VirtualDisk.TYPE_FILE \
-           and not(hvm) and virtinst.util.is_blktap_capable():
-            d.driver_name = virtinst.VirtualDisk.DRIVER_TAP
+        if d.type == virtinst.VirtualDisk.TYPE_FILE and not(hvm):
+            if virtinst.util.is_blktap_capable():
+                d.driver_name = virtinst.VirtualDisk.DRIVER_TAP
+            elif virtinst.util.is_vdisk(path):
+                d.driver_name = Guest.VirtualDisk.DRIVER_TAP
+                d.driver_type = Guest.VirtualDisk.DRIVER_TAP_VDISK
+
     except ValueError, e:
         fail(_("Error with storage parameters: %s" % str(e)))
 
diff --git a/virtinst/CloneManager.py b/virtinst/CloneManager.py
--- a/virtinst/CloneManager.py
+++ b/virtinst/CloneManager.py
@@ -19,7 +19,6 @@
 # MA 02110-1301 USA.
 
 import os
-import stat
 import libxml2
 import logging
 import urlgrabber.progress as progress
@@ -394,13 +393,9 @@ class CloneDesign(object):
         logging.debug("original device list: %s" % (lst))
 
         for i in lst:
-            mode = os.stat(i)[stat.ST_MODE]
-            if stat.S_ISBLK(mode):
-                size.append(util.blkdev_size(i))
-                typ.append(False)
-            elif stat.S_ISREG(mode):
-                size.append(os.path.getsize(i))
-                typ.append(True)
+            (t, sz) = util.stat_disk(i)
+            typ.append(t)
+            size.append(sz)
         logging.debug("original device size: %s" % (size))
         logging.debug("original device type: %s" % (typ))
 
@@ -443,18 +438,9 @@ class CloneDesign(object):
         typ  = []
 
         for i in cln_dev_lst:
-            if os.path.exists(i) ==  False:
-                size.append(0)
-                # if not exists, create file necessary
-                typ.append(True)
-                continue
-            mode = os.stat(i)[stat.ST_MODE]
-            if stat.S_ISBLK(mode):
-                size.append(util.blkdev_size(i))
-                typ.append(False)
-            elif stat.S_ISREG(mode):
-                size.append(os.path.getsize(i))
-                typ.append(True)
+            (t, sz) = util.stat_disk(i)
+            typ.append(t)
+            size.append(sz)
 
         logging.debug("clone device list: %s" % (cln_dev_lst))
         logging.debug("clone device size: %s" % (size))
@@ -535,6 +521,14 @@ def _do_duplicate(design):
             if src_dev == "/dev/null" or src_dev == dst_dev:
                 meter.end(size)
                 continue
+
+            if util.is_vdisk(src_dev) or (os.path.exists(dst_dev) and util.is_vdisk(dst_dev)):
+                if not util.is_vdisk(src_dev) or os.path.exists(dst_dev):
+                    raise RuntimeError, _("copying to an existing vdisk is not supported")
+                if not util.vdisk_clone(src_dev, dst_dev):
+                    raise RuntimeError, _("failed to clone disk")
+                continue
+
             #
             # create sparse file
             # if a destination file exists and sparse flg is True,
diff --git a/virtinst/Guest.py b/virtinst/Guest.py
--- a/virtinst/Guest.py
+++ b/virtinst/Guest.py
@@ -474,6 +474,9 @@ class Installer(object):
            or guest.disks[0].device != VirtualDisk.DEVICE_DISK:
             return True
 
+        if util.is_vdisk(guest.disks[0].path):
+            return True
+
         # Check for the 0xaa55 signature at the end of the MBR
         try:
             fd = os.open(guest.disks[0].path, os.O_RDONLY)
diff --git a/virtinst/ImageManager.py b/virtinst/ImageManager.py
--- a/virtinst/ImageManager.py
+++ b/virtinst/ImageManager.py
@@ -101,8 +101,13 @@ class ImageInstaller(Guest.Installer):
             d = VirtualDisk(p, s,
                             device = device,
                             type = VirtualDisk.TYPE_FILE)
-            if self.boot_caps.type == "xen" and util.is_blktap_capable():
-                d.driver_name = VirtualDisk.DRIVER_TAP
+            if util.is_vdisk(p):
+                d.driver_name = Guest.VirtualDisk.DRIVER_TAP
+                d.driver_type = Guest.VirtualDisk.DRIVER_TAP_VDISK
+            else:
+                if self.boot_caps.type == "xen" and util.is_blktap_capable():
+                    d.driver_name = Guest.VirtualDisk.DRIVER_TAP
+
             d.target = m.target
 
             guest._install_disks.append(d)
diff --git a/virtinst/VirtualDisk.py b/virtinst/VirtualDisk.py
--- a/virtinst/VirtualDisk.py
+++ b/virtinst/VirtualDisk.py
@@ -68,7 +68,9 @@ class VirtualDisk(VirtualDevice):
     DRIVER_TAP_RAW = "aio"
     DRIVER_TAP_QCOW = "qcow"
     DRIVER_TAP_VMDK = "vmdk"
-    driver_types = [DRIVER_TAP_RAW, DRIVER_TAP_QCOW, DRIVER_TAP_VMDK]
+    DRIVER_TAP_VDISK = "vdisk"
+    driver_types = [DRIVER_TAP_RAW, DRIVER_TAP_QCOW,
+        DRIVER_TAP_VMDK, DRIVER_TAP_VDISK]
 
     DEVICE_DISK = "disk"
     DEVICE_CDROM = "cdrom"
@@ -424,7 +426,8 @@ class VirtualDisk(VirtualDevice):
                         or self.vol_object):
             logging.debug("VirtualDisk storage exists.")
 
-            if using_path and os.path.isdir(self.path):
+            if (using_path and os.path.isdir(self.path) and
+                not util.is_vdisk(self.path)):
                 raise ValueError, _("The path must be a file or a device,"
                                     " not a directory")
             self.__set_dev_type()
@@ -476,9 +479,24 @@ class VirtualDisk(VirtualDevice):
             self._set_vol_object(self.vol_install.install(meter=progresscb),
                                  validate=False)
             return
-        elif self.type == VirtualDisk.TYPE_FILE and self.path is not None \
-             and not os.path.exists(self.path):
+        elif (self.type == VirtualDisk.TYPE_FILE and self.path is not None
+            and os.path.exists(self.path) and util.is_vdisk(self.path)):
+            self._driverName = self.DRIVER_TAP
+            self._driverType = self.DRIVER_TAP_VDISK
+            return
+        elif (self.type == VirtualDisk.TYPE_FILE and self.path is not None
+             and not os.path.exists(self.path)):
             size_bytes = long(self.size * 1024L * 1024L * 1024L)
+
+            if util.is_vdisk(self.path):
+                progresscb.update(1024)
+                if (not util.vdisk_create(self.path, size_bytes, "vmdk",
+                    self.sparse)):
+                    raise RuntimeError, _("Error creating vdisk %s" % self.path)
+                self._driverName = self.DRIVER_TAP
+                self._driverType = self.DRIVER_TAP_VDISK
+                progresscb.end(self.size)
+                return
 
             if progresscb:
                 progresscb.start(filename=self.path,size=long(size_bytes), \
diff --git a/virtinst/util.py b/virtinst/util.py
--- a/virtinst/util.py
+++ b/virtinst/util.py
@@ -29,6 +29,7 @@ import stat
 import stat
 import popen2
 from sys import stderr
+from subprocess import call
 
 import libvirt
 from virtinst import _virtinst as _
@@ -283,17 +284,71 @@ def xml_escape(str):
     str = str.replace(">", ">")
     return str
  
-def blkdev_size(path):
-    if platform.system() == 'SunOS':
-        return os.stat(path)[stat.ST_SIZE]
-    else:
-        dummy, msg = commands.getstatusoutput('fdisk -s %s' % path)
-        # check
-        if msg.isdigit() == False:
-            lines = msg.splitlines()
-            # retry eg. for the GPT disk
-            msg = lines[len(lines)-1]
-        return (int(msg) * 1024)
+def is_vdisk(path):
+    if not os.path.exists("/usr/sbin/vdiskadm"):
+        return False
+    if not os.path.exists(path):
+        return True
+    if os.path.isdir(path) and \
+       os.path.exists(path + "/vdisk.xml"):
+        return True
+    return False
+
+def vdisk_create(path, size, kind, sparse = True):
+    force_fixed = "raw"
+    path = os.path.expanduser(path)
+    if kind in force_fixed or not sparse:
+        type = kind + ":fixed"
+    else:
+        type = kind + ":sparse"
+    args = " create -t " + type + " -s " + str(size) + " " + path
+    try:
+        rc = call("/usr/sbin/vdiskadm" + args, shell=True)
+        if rc != 0:
+            return False
+        return True
+    except OSError, e:
+        return False
+
+def vdisk_clone(path, clone):
+    path = os.path.expanduser(path)
+    clone = os.path.expanduser(clone)
+    args = path + " " + clone
+    try:
+        rc = call("/usr/sbin/vdiskadm clone " + args, shell=True)
+        if rc != 0:
+            return False
+        return True
+    except OSError, e:
+        return False
+
+def stat_disk(path):
+    """Returns the tuple (isreg, size)."""
+    if not os.path.exists(path):
+        return True, 0
+
+    if is_vdisk(path):
+        size = int(commands.getoutput(
+            "vdiskadm prop-get -p max-size " + path))
+        return True, size
+
+    mode = os.stat(path)[stat.ST_MODE]
+    if stat.S_ISBLK(mode):
+        if platform.system() == 'SunOS':
+            size = os.stat(path)[stat.ST_SIZE]
+        else:
+            dummy, msg = commands.getstatusoutput('fdisk -s %s' % path)
+            # check
+            if msg.isdigit() == False:
+                lines = msg.splitlines()
+                # retry eg. for the GPT disk
+                msg = lines[len(lines)-1]
+            size = int(msg) * 1024
+        return False, size
+    elif stat.S_ISREG(mode):
+        return True, os.path.getsize(path)
+
+    return True, 0
 
 def compareMAC(p, q):
     """Compare two MAC addresses"""




More information about the et-mgmt-tools mailing list