Merge "libvirt: update logic to configure device for scsi controller" into stable/ocata

This commit is contained in:
Jenkins 2017-08-12 11:06:13 +00:00 committed by Gerrit Code Review
commit 7826df3ece
4 changed files with 61 additions and 7 deletions

View File

@ -198,7 +198,8 @@ class ImageBackendFixture(fixtures.Fixture):
self.imported_files.append((local_filename, remote_filename))
def _fake_libvirt_info(self, mock_disk, disk_bus, disk_dev, device_type,
cache_mode, extra_specs, hypervisor_version):
cache_mode, extra_specs, hypervisor_version,
disk_unit=None):
# For tests in test_virt_drivers which expect libvirt_info to be
# functional
info = config.LibvirtConfigGuestDisk()

View File

@ -3423,12 +3423,24 @@ class LibvirtConnTestCase(test.NoDBTestCase):
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(cfg.devices[2].target_dev, disk)
def test_get_guest_config_with_virtio_scsi_bus(self):
def test_get_guest_config_default_with_virtio_scsi_bus(self):
self._test_get_guest_config_with_virtio_scsi_bus()
@mock.patch.object(rbd_utils.RBDDriver, 'get_mon_addrs')
@mock.patch.object(rbd_utils, 'rbd')
def test_get_guest_config_rbd_with_virtio_scsi_bus(
self, mock_rdb, mock_get_mon_addrs):
self.flags(images_type='rbd', group='libvirt')
mock_get_mon_addrs.return_value = ("host", 9876)
self._test_get_guest_config_with_virtio_scsi_bus()
def _test_get_guest_config_with_virtio_scsi_bus(self):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
image_meta = objects.ImageMeta.from_dict({
"disk_format": "raw",
"properties": {"hw_scsi_model": "virtio-scsi"}})
"properties": {"hw_scsi_model": "virtio-scsi",
"hw_disk_bus": "scsi"}})
instance_ref = objects.Instance(**self.test_instance)
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
@ -3438,8 +3450,10 @@ class LibvirtConnTestCase(test.NoDBTestCase):
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
self.assertIsInstance(cfg.devices[0],
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(0, cfg.devices[0].device_addr.unit)
self.assertIsInstance(cfg.devices[1],
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(1, cfg.devices[1].device_addr.unit)
self.assertIsInstance(cfg.devices[2],
vconfig.LibvirtConfigGuestController)
self.assertEqual(cfg.devices[2].model, 'virtio-scsi')

View File

@ -3546,6 +3546,7 @@ class LibvirtDriver(driver.ComputeDriver):
{'qemu': MIN_QEMU_DISCARD_VERSION})
raise exception.Invalid(msg)
disk_unit = None
disk = self.image_backend.by_name(instance, name, image_type)
if (name == 'disk.config' and image_type == 'rbd' and
not disk.exists()):
@ -3561,12 +3562,17 @@ class LibvirtDriver(driver.ComputeDriver):
LOG.debug('Config drive not found in RBD, falling back to the '
'instance directory', instance=instance)
disk_info = disk_mapping[name]
return disk.libvirt_info(disk_info['bus'],
if 'unit' in disk_mapping:
disk_unit = disk_mapping['unit']
disk_mapping['unit'] += 1 # Increments for the next disk added
conf = disk.libvirt_info(disk_info['bus'],
disk_info['dev'],
disk_info['type'],
self.disk_cachemode,
inst_type['extra_specs'],
self._host.get_version())
self._host.get_version(),
disk_unit=disk_unit)
return conf
def _get_guest_fs_config(self, instance, name, image_type=None):
disk = self.image_backend.by_name(instance, name, image_type)
@ -3584,6 +3590,19 @@ class LibvirtDriver(driver.ComputeDriver):
mount_rootfs = CONF.libvirt.virt_type == "lxc"
scsi_controller = self._get_scsi_controller(image_meta)
if scsi_controller and scsi_controller.model == 'virtio-scsi':
# The virtio-scsi can handle up to 256 devices but the
# optional element "address" must be defined to describe
# where the device is placed on the controller (see:
# LibvirtConfigGuestDeviceAddressDrive).
#
# Note about why it's added in disk_mapping: It's not
# possible to pass an 'int' by reference in Python, so we
# use disk_mapping as container to keep reference of the
# unit added and be able to increment it for each disk
# added.
disk_mapping['unit'] = 0
def _get_ephemeral_devices():
eph_devices = []
for idx, eph in enumerate(
@ -3693,6 +3712,7 @@ class LibvirtDriver(driver.ComputeDriver):
scsi_controller = vconfig.LibvirtConfigGuestController()
scsi_controller.type = 'scsi'
scsi_controller.model = hw_scsi_model
scsi_controller.index = 0
return scsi_controller
def _get_host_sysinfo_serial_hardware(self):

View File

@ -118,7 +118,8 @@ class Image(object):
pass
def libvirt_info(self, disk_bus, disk_dev, device_type, cache_mode,
extra_specs, hypervisor_version, boot_order=None):
extra_specs, hypervisor_version, boot_order=None,
disk_unit=None):
"""Get `LibvirtConfigGuestDisk` filled for this image.
:disk_dev: Disk bus device name
@ -144,10 +145,24 @@ class Image(object):
info.source_path = self.path
info.boot_order = boot_order
if disk_bus == 'scsi':
self.disk_scsi(info, disk_unit)
self.disk_qos(info, extra_specs)
return info
def disk_scsi(self, info, disk_unit):
# The driver is responsible to create the SCSI controller
# at index 0.
info.device_addr = vconfig.LibvirtConfigGuestDeviceAddressDrive()
info.device_addr.controller = 0
if disk_unit is not None:
# In order to allow up to 256 disks handled by one
# virtio-scsi controller, the device addr should be
# specified.
info.device_addr.unit = disk_unit
def disk_qos(self, info, extra_specs):
tune_items = ['disk_read_bytes_sec', 'disk_read_iops_sec',
'disk_write_bytes_sec', 'disk_write_iops_sec',
@ -797,7 +812,8 @@ class Rbd(Image):
self.discard_mode = CONF.libvirt.hw_disk_discard
def libvirt_info(self, disk_bus, disk_dev, device_type, cache_mode,
extra_specs, hypervisor_version, boot_order=None):
extra_specs, hypervisor_version, boot_order=None,
disk_unit=None):
"""Get `LibvirtConfigGuestDisk` filled for this image.
:disk_dev: Disk bus device name
@ -833,6 +849,9 @@ class Rbd(Image):
info.auth_secret_type = 'ceph'
info.auth_secret_uuid = CONF.libvirt.rbd_secret_uuid
if disk_bus == 'scsi':
self.disk_scsi(info, disk_unit)
self.disk_qos(info, extra_specs)
return info