Merge "XenAPI: Add the mechanism to attach a pci device to a VM."

This commit is contained in:
Jenkins
2014-02-20 00:10:44 +00:00
committed by Gerrit Code Review
3 changed files with 87 additions and 27 deletions

View File

@@ -19,6 +19,7 @@ import mock
from nova.compute import power_state
from nova.compute import task_states
from nova import exception
from nova.pci import pci_manager
from nova import test
from nova.tests.virt.xenapi import stubs
from nova.virt import fake
@@ -216,6 +217,8 @@ class SpawnTestCase(VMOpsTestBase):
self.mox.StubOutWithMock(self.vmops, '_create_vm_record')
self.mox.StubOutWithMock(self.vmops, '_destroy')
self.mox.StubOutWithMock(self.vmops, '_attach_disks')
self.mox.StubOutWithMock(pci_manager, 'get_instance_pci_devs')
self.mox.StubOutWithMock(vm_utils, 'set_other_config_pci')
self.mox.StubOutWithMock(self.vmops, '_attach_orig_disk_for_rescue')
self.mox.StubOutWithMock(self.vmops, 'inject_network_info')
self.mox.StubOutWithMock(self.vmops, '_inject_hostname')
@@ -236,8 +239,8 @@ class SpawnTestCase(VMOpsTestBase):
'apply_instance_filter')
def _test_spawn(self, name_label_param=None, block_device_info_param=None,
rescue=False, include_root_vdi=True,
throw_exception=None):
rescue=False, include_root_vdi=True, throw_exception=None,
attach_pci_dev=False):
self._stub_out_common()
instance = {"name": "dummy", "uuid": "fake_uuid"}
@@ -293,6 +296,30 @@ class SpawnTestCase(VMOpsTestBase):
self.vmops._attach_disks(instance, vm_ref, name_label, vdis, di_type,
network_info, admin_password, injected_files)
if attach_pci_dev:
fake_dev = {
'created_at': None,
'updated_at': None,
'deleted_at': None,
'deleted': None,
'id': 1,
'compute_node_id': 1,
'address': '00:00.0',
'vendor_id': '1234',
'product_id': 'abcd',
'dev_type': 'type-PCI',
'status': 'available',
'dev_id': 'devid',
'label': 'label',
'instance_uuid': None,
'extra_info': '{}',
}
pci_manager.get_instance_pci_devs(instance).AndReturn([fake_dev])
vm_utils.set_other_config_pci(self.vmops._session,
vm_ref,
"0/0000:00:00.0")
else:
pci_manager.get_instance_pci_devs(instance).AndReturn([])
step += 1
self.vmops._update_instance_progress(context, instance, step, steps)
@@ -354,6 +381,9 @@ class SpawnTestCase(VMOpsTestBase):
name_label_param="bob",
block_device_info_param={"root_device_name": ""})
def test_spawn_with_pci_available_on_the_host(self):
self._test_spawn(attach_pci_dev=True)
def test_spawn_performs_rollback_and_throws_exception(self):
self.assertRaises(test.TestingException, self._test_spawn,
throw_exception=test.TestingException())
@@ -401,6 +431,7 @@ class SpawnTestCase(VMOpsTestBase):
self.vmops._attach_disks(instance, vm_ref, name_label, vdis, di_type,
network_info, None, None)
self.vmops._attach_mapped_block_devices(instance, block_device_info)
pci_manager.get_instance_pci_devs(instance).AndReturn([])
self.vmops._inject_instance_metadata(instance, vm_ref)
self.vmops._inject_auto_disk_config(instance, vm_ref)

View File

@@ -2722,3 +2722,10 @@ def handle_ipxe_iso(session, instance, cd_vdi, network_info):
CONF.xenserver.ipxe_mkisofs_cmd, instance=instance)
else:
raise
def set_other_config_pci(session, vm_ref, params):
"""Set the pci key of other-config parameter to params."""
other_config = session.call_xenapi("VM.get_other_config", vm_ref)
other_config['pci'] = params
session.call_xenapi("VM.set_other_config", vm_ref, other_config)

View File

@@ -44,6 +44,7 @@ from nova.openstack.common import log as logging
from nova.openstack.common import strutils
from nova.openstack.common import timeutils
from nova.openstack.common import units
from nova.pci import pci_manager
from nova import utils
from nova.virt import configdrive
from nova.virt import driver as virt_driver
@@ -368,6 +369,48 @@ class VMOps(object):
self._ensure_instance_name_unique(name_label)
self._ensure_enough_free_mem(instance)
def attach_disks(undo_mgr, vm_ref, vdis, disk_image_type):
try:
ipxe_boot = strutils.bool_from_string(
image_meta['properties']['ipxe_boot'])
except KeyError:
ipxe_boot = False
if ipxe_boot:
if 'iso' in vdis:
vm_utils.handle_ipxe_iso(
self._session, instance, vdis['iso'], network_info)
else:
LOG.warning(_('ipxe_boot is True but no ISO image found'),
instance=instance)
if resize:
self._resize_up_vdis(instance, vdis)
self._attach_disks(instance, vm_ref, name_label, vdis,
disk_image_type, network_info, admin_password,
injected_files)
if not first_boot:
self._attach_mapped_block_devices(instance,
block_device_info)
def attach_pci_devices(undo_mgr, vm_ref):
dev_to_passthrough = ""
devices = pci_manager.get_instance_pci_devs(instance)
for d in devices:
pci_address = d["address"]
if pci_address.count(":") == 1:
pci_address = "0000:" + pci_address
dev_to_passthrough += ",0/" + pci_address
# Remove the first comma if string is not empty.
# Note(guillaume-thouvenin): If dev_to_passthrough is empty, we
# don't need to update other_config.
if dev_to_passthrough:
vm_utils.set_other_config_pci(self._session,
vm_ref,
dev_to_passthrough[1:])
@step
def determine_disk_image_type_step(undo_mgr):
return vm_utils.determine_disk_image_type(image_meta)
@@ -398,30 +441,9 @@ class VMOps(object):
return vm_ref
@step
def attach_disks_step(undo_mgr, vm_ref, vdis, disk_image_type):
try:
ipxe_boot = strutils.bool_from_string(
image_meta['properties']['ipxe_boot'])
except KeyError:
ipxe_boot = False
if ipxe_boot:
if 'iso' in vdis:
vm_utils.handle_ipxe_iso(
self._session, instance, vdis['iso'], network_info)
else:
LOG.warning(_('ipxe_boot is True but no ISO image found'),
instance=instance)
if resize:
self._resize_up_vdis(instance, vdis)
self._attach_disks(instance, vm_ref, name_label, vdis,
disk_image_type, network_info, admin_password,
injected_files)
if not first_boot:
self._attach_mapped_block_devices(instance,
block_device_info)
def attach_devices_step(undo_mgr, vm_ref, vdis, disk_image_type):
attach_disks(undo_mgr, vm_ref, vdis, disk_image_type)
attach_pci_devices(undo_mgr, vm_ref)
if rescue:
# NOTE(johannes): Attach root disk to rescue VM now, before
@@ -486,7 +508,7 @@ class VMOps(object):
vm_ref = create_vm_record_step(undo_mgr, disk_image_type,
kernel_file, ramdisk_file)
attach_disks_step(undo_mgr, vm_ref, vdis, disk_image_type)
attach_devices_step(undo_mgr, vm_ref, vdis, disk_image_type)
inject_instance_data_step(undo_mgr, vm_ref, vdis)
setup_network_step(undo_mgr, vm_ref)