[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