mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Import 83:b569bb25a8f08a15381b022ee143d7f205976604 from xen-api.hg, minus the
Makefile patch. [XEND] Remove blank image file generation for QCOW images. There is no need for a blank backing store, although this means we have to find a new way to determine how much virtual disk space is free in the StorageRepository. Beginnings to attempt to supoprt HVM guests. Signed-off-by: Alastair Tse <atse@xensource.com>
This commit is contained in:
1 parent
c09512317b
commit
4ed8357baa
6 files changed
+47
-48
No files matched your search
@@ -61,7 +61,7 @@ OPTIONS = {
|
||||
'vm-shutdown': [(('-f', '--force'), {'help': 'Shutdown Forcefully',
|
||||
'action': 'store_true'})],
|
||||
|
||||
'vdi-create': [(('--label',), {'help': 'Name for VDI'}),
|
||||
'vdi-create': [(('--name-label',), {'help': 'Name for VDI'}),
|
||||
(('--description',), {'help': 'Description for VDI'}),
|
||||
(('--sector-size',), {'type': 'int',
|
||||
'help': 'Sector size'}),
|
||||
@@ -279,13 +279,17 @@ def xapi_vbd_create(*args):
|
||||
raise OptionError("Configuration file and domain not specified")
|
||||
|
||||
domname = args[0]
|
||||
filename = args[1]
|
||||
|
||||
cfg = _read_python_cfg(filename)
|
||||
if len(args) > 1:
|
||||
filename = args[1]
|
||||
cfg = _read_python_cfg(filename)
|
||||
else:
|
||||
cfg = {}
|
||||
|
||||
for opt, val in opts:
|
||||
cfg[opt] = val
|
||||
|
||||
print 'Creating VBD from %s ..' % filename
|
||||
print 'Creating VBD ...',
|
||||
server, session = _connect()
|
||||
vm_uuid = resolve_vm(server, session, domname)
|
||||
cfg['VM'] = vm_uuid
|
||||
@@ -335,10 +339,11 @@ def xapi_sr_list(*args):
|
||||
def xapi_vdi_create(*args):
|
||||
opts, args = parse_args('vdi-create', args)
|
||||
|
||||
if len(args) < 1:
|
||||
raise OptionError("Not enough arguments.")
|
||||
|
||||
cfg = _read_python_cfg(args[0])
|
||||
if len(args) > 0:
|
||||
cfg = _read_python_cfg(args[0])
|
||||
else:
|
||||
cfg = {}
|
||||
|
||||
for opt, val in opts:
|
||||
cfg[opt] = val
|
||||
|
||||
@@ -348,7 +353,7 @@ def xapi_vdi_create(*args):
|
||||
cfg['SR'] = sr
|
||||
|
||||
size = (cfg['virtual_size'] * cfg['sector_size'])/MB
|
||||
print 'Creating VDI of size: %dMB' % size
|
||||
print 'Creating VDI of size: %dMB ..' % size,
|
||||
uuid = execute(server.VDI.create, session, cfg)
|
||||
print 'Done. (%s)' % uuid
|
||||
|
||||
@@ -378,6 +383,8 @@ def xapi_vdi_rename(*args):
|
||||
# Command Line Utils
|
||||
#
|
||||
import cmd
|
||||
import shlex
|
||||
|
||||
class XenAPICmd(cmd.Cmd):
|
||||
def __init__(self, server, session):
|
||||
cmd.Cmd.__init__(self)
|
||||
@@ -386,7 +393,7 @@ class XenAPICmd(cmd.Cmd):
|
||||
self.prompt = ">>> "
|
||||
|
||||
def default(self, line):
|
||||
words = line.split()
|
||||
words = shlex.split(line)
|
||||
if len(words) > 0:
|
||||
cmd_name = words[0].replace('-', '_')
|
||||
func_name = 'xapi_%s' % cmd_name
|
||||
@@ -415,11 +422,14 @@ class XenAPICmd(cmd.Cmd):
|
||||
def do_help(self, line):
|
||||
usage(print_usage = False)
|
||||
|
||||
def emptyline(self):
|
||||
pass
|
||||
|
||||
def postcmd(self, stop, line):
|
||||
return False
|
||||
|
||||
def precmd(self, line):
|
||||
words = line.split()
|
||||
words = shlex.split(line)
|
||||
if len(words) > 0:
|
||||
words0 = words[0].replace('-', '_')
|
||||
return ' '.join([words0] + words[1:])
|
||||
|
||||
@@ -1038,8 +1038,10 @@ class XendAPI:
|
||||
def vbd_get_vm(self, session, vbd_ref):
|
||||
xendom = XendDomain.instance()
|
||||
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
|
||||
|
||||
def vbd_get_vdi(self, session, vbd_ref):
|
||||
return xen_api_error(XEND_ERROR_UNSUPPORTED)
|
||||
return xen_api_todo()
|
||||
|
||||
def vbd_get_device(self, session, vbd_ref):
|
||||
xendom = XendDomain.instance()
|
||||
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
|
||||
|
||||
@@ -89,6 +89,13 @@ XENAPI_CFG_CUSTOM_TRANSLATE = [
|
||||
'vbds',
|
||||
]
|
||||
|
||||
XENAPI_HVM_CFG = {
|
||||
'platform_std_vga': 'std-vga',
|
||||
'platform_serial' : 'serial',
|
||||
'platform_localtime': 'localtime',
|
||||
'platform_enable_audio': 'soundhw',
|
||||
}
|
||||
|
||||
XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
|
||||
'name_description',
|
||||
'user_version',
|
||||
@@ -117,6 +124,7 @@ XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
|
||||
'otherconfig'
|
||||
]
|
||||
|
||||
|
||||
# configuration params that need to be converted to ints
|
||||
# since the XMLRPC transport for Xen API does not use
|
||||
# 32 bit ints but string representation of 64 bit ints.
|
||||
@@ -505,7 +513,6 @@ class XendConfig(dict):
|
||||
raise XendConfigError('integer expeceted: %s: %s' %
|
||||
str(cfg['image']), e)
|
||||
|
||||
|
||||
# Deprecated cpu configuration
|
||||
if 'cpu' in cfg:
|
||||
if 'cpus' in cfg:
|
||||
@@ -593,6 +600,7 @@ class XendConfig(dict):
|
||||
sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']])
|
||||
if xenapi_vm['kernel_args']:
|
||||
sxp_image.append(['args', xenapi_vm['kernel_args']])
|
||||
|
||||
cfg['image'] = prettyprintstring(sxp_image)
|
||||
|
||||
# make sure device structures are there.
|
||||
|
||||
@@ -91,7 +91,7 @@ class XendDomain:
|
||||
try:
|
||||
try:
|
||||
dom0info = [d for d in self._running_domains() \
|
||||
if d['domid'] == DOM0_ID][0]
|
||||
if d.get('domid') == DOM0_ID][0]
|
||||
|
||||
dom0info['name'] = DOM0_NAME
|
||||
dom0 = XendDomainInfo.recreate(dom0info, True)
|
||||
|
||||
@@ -30,10 +30,9 @@ from xen.xend.XendVDI import *
|
||||
XEND_STORAGE_MAX_IGNORE = -1
|
||||
XEND_STORAGE_DIR = "/var/lib/xend/storage/"
|
||||
XEND_STORAGE_QCOW_FILENAME = "%s.qcow"
|
||||
XEND_STORAGE_IMG_FILENAME = "%s.img"
|
||||
XEND_STORAGE_VDICFG_FILENAME = "%s.vdi.xml"
|
||||
DF_COMMAND = "df -lPk"
|
||||
QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s %s"
|
||||
QCOW_CREATE_COMMAND = "/usr/sbin/qcow-create %d %s"
|
||||
|
||||
KB = 1024
|
||||
MB = 1024 *1024
|
||||
@@ -113,34 +112,29 @@ class XendStorageRepository:
|
||||
image_uuid = filename[:-5]
|
||||
seen_images.append(image_uuid)
|
||||
if image_uuid not in self.images:
|
||||
image_file = XEND_STORAGE_IMG_FILENAME % image_uuid
|
||||
qcow_file = XEND_STORAGE_QCOW_FILENAME % image_uuid
|
||||
cfg_file = XEND_STORAGE_VDICFG_FILENAME % image_uuid
|
||||
|
||||
image_path = os.path.join(XEND_STORAGE_DIR,image_file)
|
||||
qcow_path = os.path.join(XEND_STORAGE_DIR, qcow_file)
|
||||
cfg_path = os.path.join(XEND_STORAGE_DIR, cfg_file)
|
||||
|
||||
qcow_size = os.stat(qcow_path).st_size
|
||||
image_size = os.stat(image_path).st_size
|
||||
|
||||
# TODO: no way to stat virtual size of qcow
|
||||
vdi = XendQCOWVDI(image_uuid, self.uuid,
|
||||
qcow_path, image_path, cfg_path,
|
||||
image_size,
|
||||
qcow_size + image_size)
|
||||
qcow_path, cfg_path,
|
||||
qcow_size, qcow_size)
|
||||
|
||||
if cfg_path and os.path.exists(cfg_path):
|
||||
vdi.load_config(cfg_path)
|
||||
|
||||
self.images[image_uuid] = vdi
|
||||
total_used += image_size
|
||||
total_used += qcow_size
|
||||
|
||||
# remove images that aren't valid
|
||||
for image_uuid in self.images.keys():
|
||||
if image_uuid not in seen_images:
|
||||
try:
|
||||
os.unlink(self.images[image_uuid].qcow_path)
|
||||
os.unlink(self.images[image_uuid].image_path)
|
||||
except OSError:
|
||||
pass
|
||||
del self.images[image_uuid]
|
||||
@@ -218,30 +212,19 @@ class XendStorageRepository:
|
||||
raise XendError("Not enough space")
|
||||
|
||||
image_uuid = uuid.createString()
|
||||
# create file based image
|
||||
image_path = os.path.join(XEND_STORAGE_DIR,
|
||||
XEND_STORAGE_IMG_FILENAME % image_uuid)
|
||||
qcow_path = os.path.join(XEND_STORAGE_DIR,
|
||||
XEND_STORAGE_QCOW_FILENAME % image_uuid)
|
||||
|
||||
if image_path and os.path.exists(image_path):
|
||||
if qcow_path and os.path.exists(qcow_path):
|
||||
raise XendError("Image with same UUID alreaady exists:" %
|
||||
image_uuid)
|
||||
|
||||
block = '\x00' * KB
|
||||
img = open(image_path, 'w')
|
||||
for i in range(desired_size_bytes/KB):
|
||||
img.write(block)
|
||||
img.close()
|
||||
|
||||
# TODO: create qcow image
|
||||
qcow_path = os.path.join(XEND_STORAGE_DIR,
|
||||
XEND_STORAGE_QCOW_FILENAME % image_uuid)
|
||||
cmd = QCOW_CREATE_COMMAND % (desired_size_bytes/MB,
|
||||
qcow_path, image_path)
|
||||
|
||||
cmd = QCOW_CREATE_COMMAND % (desired_size_bytes/MB, qcow_path)
|
||||
rc, output = commands.getstatusoutput(cmd)
|
||||
|
||||
if rc != 0:
|
||||
# cleanup the image file
|
||||
os.unlink(image_path)
|
||||
os.unlink(qcow_path)
|
||||
raise XendError("Failed to create QCOW Image: %s" % output)
|
||||
|
||||
self._refresh()
|
||||
@@ -261,11 +244,9 @@ class XendStorageRepository:
|
||||
if image_uuid in self.images:
|
||||
# TODO: check if it is being used?
|
||||
qcow_path = self.images[image_uuid].qcow_path
|
||||
image_path = self.images[image_uuid].image_path
|
||||
cfg_path = self.images[image_uuid].cfg_path
|
||||
try:
|
||||
os.unlink(qcow_path)
|
||||
os.unlink(image_path)
|
||||
if cfg_path and os.path.exists(cfg_path):
|
||||
os.unlink(cfg_path)
|
||||
except OSError:
|
||||
|
||||
@@ -143,15 +143,13 @@ class XendVDI(AutoSaveObject):
|
||||
|
||||
class XendQCOWVDI(XendVDI):
|
||||
|
||||
def __init__(self, uuid, sr_uuid, qcow_path, image_path, cfg_path,
|
||||
vsize, psize):
|
||||
def __init__(self, uuid, sr_uuid, qcow_path, cfg_path, vsize, psize):
|
||||
XendVDI.__init__(self, uuid, sr_uuid)
|
||||
self.auto_save = False
|
||||
self.qcow_path = qcow_path
|
||||
self.image_path = image_path
|
||||
self.cfg_path = cfg_path
|
||||
self.physical_utilisation = psize
|
||||
self.virtual_size = vsize
|
||||
self.sector_size = 1
|
||||
self.sector_size = 512
|
||||
self.auto_save = True
|
||||
|
||||