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

john.levon at sun.com john.levon at sun.com
Wed Dec 10 19:34:31 UTC 2008


# HG changeset patch
# User john.levon at sun.com
# Date 1228937605 28800
# Node ID fa56f55633ea7af14af4dd260a00b020a69a2fea
# Parent  8638073ea45665c7531931515636a862f684c2a5
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/virtinst/CloneManager.py b/virtinst/CloneManager.py
--- a/virtinst/CloneManager.py
+++ b/virtinst/CloneManager.py
@@ -21,6 +21,7 @@ import os
 import os
 import libxml2
 import logging
+import subprocess
 import urlgrabber.progress as progress
 import _util
 import libvirt
@@ -492,6 +493,15 @@ def start_duplicate(design):
 
     logging.debug("start_duplicate out")
 
+def _vdisk_clone(path, clone):
+    path = os.path.expanduser(path)
+    clone = os.path.expanduser(clone)
+    try:
+        rc = subprocess.call([ '/usr/sbin/vdiskadm', 'clone', path, clone ])
+        return rc == 0
+    except OSError, e:
+        return False
+
 #
 # Now this Cloning method is reading and writing devices.
 # For future, there are many cloning methods (e.g. fork snapshot cmd).
@@ -521,6 +531,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 _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/VirtualDisk.py b/virtinst/VirtualDisk.py
--- a/virtinst/VirtualDisk.py
+++ b/virtinst/VirtualDisk.py
@@ -20,6 +20,7 @@
 # MA 02110-1301 USA.
 
 import os, stat, statvfs
+import subprocess
 import libxml2
 import logging
 import libvirt
@@ -28,6 +29,20 @@ import Storage
 import Storage
 from VirtualDevice import VirtualDevice
 from virtinst import _virtinst as _
+
+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"
+    try:
+        rc = subprocess.call([ '/usr/sbin/vdiskadm', 'create', '-t', type,
+            '-s', str(size), path ])
+        return rc == 0
+    except OSError, e:
+        return False
 
 class VirtualDisk(VirtualDevice):
     """
@@ -68,7 +83,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"
@@ -143,6 +160,10 @@ class VirtualDisk(VirtualDevice):
         if volName:
             self.__lookup_vol_name(volName)
 
+        if self._type == self.TYPE_FILE and _util.is_vdisk(self._path):
+            self._driverName = self.DRIVER_TAP
+            self._driverType = self.DRIVER_TAP_VDISK
+
         self.__validate_params()
 
 
@@ -285,6 +306,9 @@ class VirtualDisk(VirtualDevice):
                 dtype = self.TYPE_BLOCK
             else:
                 dtype = self.TYPE_FILE
+            if _util.is_vdisk(self.path):
+                self._driverName = self.DRIVER_TAP
+                self._driverType = self.DRIVER_TAP_VDISK
 
         logging.debug("Detected storage as type '%s'" % dtype)
         if self.type is not None and dtype != self.type:
@@ -424,7 +448,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,13 +501,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 not os.path.exists(self.path)):
             size_bytes = long(self.size * 1024L * 1024L * 1024L)
 
             if progresscb:
                 progresscb.start(filename=self.path,size=long(size_bytes), \
                                  text=_("Creating storage file..."))
+
+            if _util.is_vdisk(self.path):
+                progresscb.update(1024)
+                if (not _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
+
             fd = None
             try:
                 try:
diff --git a/virtinst/_util.py b/virtinst/_util.py
--- a/virtinst/_util.py
+++ b/virtinst/_util.py
@@ -23,15 +23,31 @@
 # not be used by clients.
 #
 
+import commands
 import stat
 import os
 
 from virtinst import util
 
+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 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]
    




More information about the et-mgmt-tools mailing list