# HG changeset patch # User john.levon@xxxxxxx # 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@xxxxxxx> 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] _______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools