summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalvatore Orlando <salvatore.orlando@eu.citrix.com>2010-12-14 16:32:28 +0000
committerSalvatore Orlando <salvatore.orlando@eu.citrix.com>2010-12-14 16:32:28 +0000
commit41203e726fd3e43bcce7f800c6bf042e9dd70531 (patch)
tree34a0759f2dd562e935dddfd6255960a53300a367
parent49a1cadd61b4badff0578ecd26adb57fb284ad9a (diff)
downloadnova-41203e726fd3e43bcce7f800c6bf042e9dd70531.tar.gz
nova-41203e726fd3e43bcce7f800c6bf042e9dd70531.tar.xz
nova-41203e726fd3e43bcce7f800c6bf042e9dd70531.zip
support for pv guests (in progress)
-rw-r--r--nova/virt/xenapi/vm_utils.py45
-rw-r--r--nova/virt/xenapi/vmops.py8
-rw-r--r--plugins/xenapi/etc/xapi.d/plugins/objectstore30
3 files changed, 63 insertions, 20 deletions
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index 3ab4581c4..eeceb8e71 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -47,9 +47,11 @@ class VMHelper():
@classmethod
@defer.inlineCallbacks
- def create_vm(cls, session, instance, kernel, ramdisk):
+ def create_vm(cls, session, instance, kernel, ramdisk,pv_kernel=False):
"""Create a VM record. Returns a Deferred that gives the new
- VM reference."""
+ VM reference.
+ the pv_kernel flag indicates whether the guest is HVM or PV
+ """
instance_type = instance_types.INSTANCE_TYPES[instance.instance_type]
mem = str(long(instance_type['memory_mb']) * 1024 * 1024)
@@ -79,7 +81,7 @@ class VMHelper():
'platform': {},
'PCI_bus': '',
'recommendations': '',
- 'affinity': '',
+ 'affinity': '',
'user_version': '0',
'other_config': {},
}
@@ -94,11 +96,14 @@ class VMHelper():
rec['PV_bootloader_args'] = ''
rec['PV_legacy_args'] = ''
else:
- logging.debug("This a raw image, hopefully HVM")
- #TODO: Windows needs a platform flag...
- rec['HVM_boot_policy'] = 'BIOS order'
- rec['HVM_boot_params'] = {'order': 'dc'}
-
+ logging.debug("This a raw image")
+ if (pv_kernel):
+ rec['PV_args'] = 'noninteractive'
+ rec['PV_bootloader'] = 'pygrub'
+ else:
+ rec['HVM_boot_policy'] = 'BIOS order'
+ rec['HVM_boot_params'] = {'order': 'dc'}
+ rec['platform']={'acpi':'true','apic':'true','pae':'true','viridian':'true'}
logging.debug('Created VM %s...', instance.name)
vm_ref = yield session.call_xenapi('VM.create', rec)
logging.debug('Created VM %s as %s.', instance.name, vm_ref)
@@ -162,23 +167,39 @@ class VMHelper():
url = images.image_url(image)
access = AuthManager().get_access_key(user, project)
logging.debug("Asking xapi to fetch %s as %s", url, access)
- fn = use_sr and 'get_vdi' or 'get_kernel'
+ logging.debug("Salvatore: image type = %d",type)
+ fn = (type<>0) and 'get_vdi' or 'get_kernel'
+ logging.debug("Salvatore: fn=%s",fn)
args = {}
args['src_url'] = url
args['username'] = access
args['password'] = user.secret
args['add_partition']='false'
args['raw']='false'
- if use_sr<>0:
+ if type<>0:
args['add_partition'] = 'true'
- else:
- if use_sr==2:
+ if type==2:
args['raw']='true'
+ logging.debug("Salvatore: args['raw']=%s",args['raw'])
+ logging.debug("Salvatore: args['add_partition']=%s",args['add_partition'])
task = yield session.async_call_plugin('objectstore', fn, args)
uuid = yield session.wait_for_task(task)
defer.returnValue(uuid)
@classmethod
+ @defer.inlineCallbacks
+ def lookup_image(cls, session, vdi_ref):
+ logging.debug("Looking up vdi %s for PV kernel",vdi_ref)
+ fn="is_vdi_pv"
+ args={}
+ args['vdi-ref']=vdi_ref
+ #TODO: Call proper function in plugin
+ task = yield session.async_call_plugin('objectstore', fn, args)
+ pv=yield session.wait_for_task(task)
+ logging.debug("PV Kernel in VDI:%d",pv)
+ defer.returnValue(pv)
+
+ @classmethod
@utils.deferredToThread
def lookup(cls, session, i):
""" Look the instance i up, and returns it if available """
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 3646965b1..17379e9f2 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -64,6 +64,11 @@ class VMOps(object):
disk_image_type=2
vdi_uuid = yield VMHelper.fetch_image(self._session,
instance.image_id, user, project, disk_image_type)
+ vdi_ref = yield self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)
+ #Have a look at the VDI and see if it has a PV kernel
+ pv_kernel=False
+ if (not instance.kernel_id):
+ pv_kernel=yield VMHelper.lookup_image(self._session,vdi_ref)
kernel=None
if (instance.kernel_id):
kernel = yield VMHelper.fetch_image(self._session,
@@ -72,9 +77,8 @@ class VMOps(object):
if (instance.ramdisk_id):
ramdisk = yield VMHelper.fetch_image(self._session,
instance.ramdisk_id, user, project, 0)
- vdi_ref = yield self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)
vm_ref = yield VMHelper.create_vm(self._session,
- instance, kernel, ramdisk)
+ instance, kernel, ramdisk,pv_kernel)
yield VMHelper.create_vbd(self._session, vm_ref, vdi_ref, 0, True)
if network_ref:
yield VMHelper.create_vif(self._session, vm_ref,
diff --git a/plugins/xenapi/etc/xapi.d/plugins/objectstore b/plugins/xenapi/etc/xapi.d/plugins/objectstore
index 071494160..bc9e783cf 100644
--- a/plugins/xenapi/etc/xapi.d/plugins/objectstore
+++ b/plugins/xenapi/etc/xapi.d/plugins/objectstore
@@ -43,25 +43,42 @@ SECTOR_SIZE = 512
MBR_SIZE_SECTORS = 63
MBR_SIZE_BYTES = MBR_SIZE_SECTORS * SECTOR_SIZE
-
+def is_vdi_pv(session,args):
+ logging.debug("Checking wheter VDI has PV kernel")
+ vdi = exists(args, 'vdi-ref')
+ pv=False
+ pv=with_vdi_in_dom0(session, vdi, False,
+ lambda dev: _is_vdi_pv('/dev/%s' % dev))
+ return pv
+
+def _is_vdi_pv(dest):
+ logging.debug("Running pygrub against %s",dest)
+ output=os.popen('pygrub -qn %s' % dest)
+ pv=False
+ for line in output.readlines():
+ logging.debug("line:",line)
+ #try to find kernel string
+ m=re.search('(?<=kernel:)/.*(?:>)',line)
+ if (m<>None):
+ if m.group(0).find('xen')<>-1:
+ pv=True
+ logging.debug("PV:%d",pv)
+ return pv
+
def get_vdi(session, args):
src_url = exists(args, 'src_url')
username = exists(args, 'username')
password = exists(args, 'password')
raw_image=validate_bool(args, 'raw', 'false')
add_partition = validate_bool(args, 'add_partition', 'false')
-
(proto, netloc, url_path, _, _, _) = urlparse.urlparse(src_url)
-
sr = find_sr(session)
if sr is None:
raise Exception('Cannot find SR to write VDI to')
-
virtual_size = \
get_content_length(proto, netloc, url_path, username, password)
if virtual_size < 0:
raise Exception('Cannot get VDI size')
-
vdi_size = virtual_size
if add_partition:
# Make room for MBR.
@@ -230,4 +247,5 @@ def download_all(response, length, dest_file, offset):
if __name__ == '__main__':
XenAPIPlugin.dispatch({'get_vdi': get_vdi,
- 'get_kernel': get_kernel})
+ 'get_kernel': get_kernel,
+ 'is_vdi_pv': is_vdi_pv})