From 41203e726fd3e43bcce7f800c6bf042e9dd70531 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Tue, 14 Dec 2010 16:32:28 +0000 Subject: support for pv guests (in progress) --- nova/virt/xenapi/vm_utils.py | 45 ++++++++++++++++++++------- nova/virt/xenapi/vmops.py | 8 +++-- plugins/xenapi/etc/xapi.d/plugins/objectstore | 30 ++++++++++++++---- 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,22 +167,38 @@ 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): 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}) -- cgit