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