xenapi: fix support for iso boot
Fixes bug 1154731 that stated the iso support was broken. There were several issues around a vdis list without a 'root' disk. Because the ISO boot was HVM, only 0-3 devices will work, so, the devices used have been re-ordered to ensure ISOs can be read by a HVM guest without PV tools. Once PV tools are present, a HVM guest will be able to access an ephemeral or swap disk. Change-Id: I4b57f70301a4256fa975323d7964fde19e8d4508
This commit is contained in:
@@ -206,13 +206,14 @@ def after_VBD_create(vbd_ref, vbd_rec):
|
||||
vm_rec = _db_content['VM'][vm_ref]
|
||||
vm_rec['VBDs'].append(vbd_ref)
|
||||
|
||||
vdi_ref = vbd_rec['VDI']
|
||||
vdi_rec = _db_content['VDI'][vdi_ref]
|
||||
vdi_rec['VBDs'].append(vbd_ref)
|
||||
|
||||
vm_name_label = _db_content['VM'][vm_ref]['name_label']
|
||||
vbd_rec['vm_name_label'] = vm_name_label
|
||||
|
||||
vdi_ref = vbd_rec['VDI']
|
||||
if vdi_ref and vdi_ref != "OpaqueRef:NULL":
|
||||
vdi_rec = _db_content['VDI'][vdi_ref]
|
||||
vdi_rec['VBDs'].append(vbd_ref)
|
||||
|
||||
|
||||
def after_VM_create(vm_ref, vm_rec):
|
||||
"""Create read-only fields in the VM record."""
|
||||
@@ -401,6 +402,12 @@ class SessionBase(object):
|
||||
def pool_get_default_SR(self, _1, pool_ref):
|
||||
return 'FAKE DEFAULT SR'
|
||||
|
||||
def VBD_insert(self, _1, vbd_ref, vdi_ref):
|
||||
vbd_rec = get_record('VBD', vbd_ref)
|
||||
get_record('VDI', vdi_ref)
|
||||
vbd_rec['empty'] = False
|
||||
vbd_rec['VDI'] = vdi_ref
|
||||
|
||||
def VBD_plug(self, _1, ref):
|
||||
rec = get_record('VBD', ref)
|
||||
if rec['currently_attached']:
|
||||
|
||||
@@ -387,17 +387,20 @@ def destroy_vbd(session, vbd_ref):
|
||||
|
||||
|
||||
def create_vbd(session, vm_ref, vdi_ref, userdevice, vbd_type='disk',
|
||||
read_only=False, bootable=False, osvol=False):
|
||||
read_only=False, bootable=False, osvol=False,
|
||||
empty=False, unpluggable=True):
|
||||
"""Create a VBD record and returns its reference."""
|
||||
vbd_rec = {}
|
||||
vbd_rec['VM'] = vm_ref
|
||||
if vdi_ref == None:
|
||||
vdi_ref = 'OpaqueRef:NULL'
|
||||
vbd_rec['VDI'] = vdi_ref
|
||||
vbd_rec['userdevice'] = str(userdevice)
|
||||
vbd_rec['bootable'] = bootable
|
||||
vbd_rec['mode'] = read_only and 'RO' or 'RW'
|
||||
vbd_rec['type'] = vbd_type
|
||||
vbd_rec['unpluggable'] = True
|
||||
vbd_rec['empty'] = False
|
||||
vbd_rec['unpluggable'] = unpluggable
|
||||
vbd_rec['empty'] = empty
|
||||
vbd_rec['other_config'] = {}
|
||||
vbd_rec['qos_algorithm_type'] = ''
|
||||
vbd_rec['qos_algorithm_params'] = {}
|
||||
@@ -415,6 +418,16 @@ def create_vbd(session, vm_ref, vdi_ref, userdevice, vbd_type='disk',
|
||||
return vbd_ref
|
||||
|
||||
|
||||
def attach_cd(session, vm_ref, vdi_ref, userdevice):
|
||||
"""Create an empty VBD, then insert the CD."""
|
||||
vbd_ref = create_vbd(session, vm_ref, None, userdevice,
|
||||
vbd_type='cd', read_only=True,
|
||||
bootable=True, empty=True,
|
||||
unpluggable=False)
|
||||
session.call_xenapi('VBD.insert', vbd_ref, vdi_ref)
|
||||
return vbd_ref
|
||||
|
||||
|
||||
def destroy_vdi(session, vdi_ref):
|
||||
try:
|
||||
session.call_xenapi('VDI.destroy', vdi_ref)
|
||||
@@ -837,6 +850,12 @@ def generate_ephemeral(session, instance, vm_ref, userdevice, name_label,
|
||||
CONF.default_ephemeral_format)
|
||||
|
||||
|
||||
def generate_iso_blank_root_disk(session, instance, vm_ref, userdevice,
|
||||
name_label, size_gb):
|
||||
_generate_disk(session, instance, vm_ref, userdevice, name_label,
|
||||
'user', size_gb * 1024, CONF.default_ephemeral_format)
|
||||
|
||||
|
||||
def generate_configdrive(session, instance, vm_ref, userdevice,
|
||||
admin_password=None, files=None):
|
||||
sr_ref = safe_find_sr(session)
|
||||
|
||||
@@ -81,9 +81,14 @@ RESIZE_TOTAL_STEPS = 5
|
||||
DEVICE_ROOT = '0'
|
||||
DEVICE_RESCUE = '1'
|
||||
DEVICE_SWAP = '2'
|
||||
DEVICE_EPHEMERAL = '3'
|
||||
DEVICE_CD = '4'
|
||||
DEVICE_CONFIGDRIVE = '5'
|
||||
DEVICE_CONFIGDRIVE = '3'
|
||||
# Note(johngarbutt) HVM guests only support four devices
|
||||
# until the PV tools activate, when others before available
|
||||
# As such, ephemeral disk only available once PV tools load
|
||||
DEVICE_EPHEMERAL = '4'
|
||||
# Note(johngarbutt) Currently don't support ISO boot during rescue
|
||||
# and we must have the ISO visible before the PV drivers start
|
||||
DEVICE_CD = '1'
|
||||
|
||||
|
||||
def cmp_version(a, b):
|
||||
@@ -529,25 +534,33 @@ class VMOps(object):
|
||||
if not vm_utils.ensure_free_mem(self._session, instance):
|
||||
raise exception.InsufficientFreeMemory(uuid=instance['uuid'])
|
||||
|
||||
mode = vm_mode.get_from_instance(instance)
|
||||
if mode == vm_mode.XEN:
|
||||
use_pv_kernel = True
|
||||
elif mode == vm_mode.HVM:
|
||||
use_pv_kernel = False
|
||||
else:
|
||||
use_pv_kernel = vm_utils.determine_is_pv(self._session,
|
||||
vdis['root']['ref'], disk_image_type, instance['os_type'])
|
||||
mode = use_pv_kernel and vm_mode.XEN or vm_mode.HVM
|
||||
|
||||
mode = self._determine_vm_mode(instance, vdis, disk_image_type)
|
||||
if instance['vm_mode'] != mode:
|
||||
# Update database with normalized (or determined) value
|
||||
self._virtapi.instance_update(context,
|
||||
instance['uuid'], {'vm_mode': mode})
|
||||
|
||||
use_pv_kernel = (mode == vm_mode.XEN)
|
||||
vm_ref = vm_utils.create_vm(self._session, instance, name_label,
|
||||
kernel_file, ramdisk_file, use_pv_kernel)
|
||||
return vm_ref
|
||||
|
||||
def _determine_vm_mode(self, instance, vdis, disk_image_type):
|
||||
current_mode = vm_mode.get_from_instance(instance)
|
||||
if current_mode == vm_mode.XEN or current_mode == vm_mode.HVM:
|
||||
return current_mode
|
||||
|
||||
is_pv = False
|
||||
if 'root' in vdis:
|
||||
os_type = instance['os_type']
|
||||
vdi_ref = vdis['root']['ref']
|
||||
is_pv = vm_utils.determine_is_pv(self._session, vdi_ref,
|
||||
disk_image_type, os_type)
|
||||
if is_pv:
|
||||
return vm_mode.XEN
|
||||
else:
|
||||
return vm_mode.HVM
|
||||
|
||||
def _attach_disks(self, instance, vm_ref, name_label, vdis,
|
||||
disk_image_type, admin_password=None, files=None):
|
||||
ctx = nova_context.get_admin_context()
|
||||
@@ -556,19 +569,14 @@ class VMOps(object):
|
||||
# Attach (required) root disk
|
||||
if disk_image_type == vm_utils.ImageType.DISK_ISO:
|
||||
# DISK_ISO needs two VBDs: the ISO disk and a blank RW disk
|
||||
LOG.debug(_("Detected ISO image type, creating blank VM "
|
||||
"for install"), instance=instance)
|
||||
root_disk_size = instance_type['root_gb']
|
||||
if root_disk_size > 0:
|
||||
vm_utils.generate_iso_blank_root_disk(self._session, instance,
|
||||
vm_ref, DEVICE_ROOT, name_label, root_disk_size)
|
||||
|
||||
cd_vdi = vdis.pop('root')
|
||||
root_vdi = vm_utils.fetch_blank_disk(self._session,
|
||||
instance_type['id'])
|
||||
vdis['root'] = root_vdi
|
||||
|
||||
vm_utils.create_vbd(self._session, vm_ref, root_vdi['ref'],
|
||||
DEVICE_ROOT, bootable=False)
|
||||
|
||||
vm_utils.create_vbd(self._session, vm_ref, cd_vdi['ref'],
|
||||
DEVICE_CD, vbd_type='CD', bootable=True)
|
||||
cd_vdi = vdis.pop('iso')
|
||||
vm_utils.attach_cd(self._session, vm_ref, cd_vdi['ref'],
|
||||
DEVICE_CD)
|
||||
else:
|
||||
root_vdi = vdis['root']
|
||||
|
||||
|
||||
Reference in New Issue
Block a user