libvirt: update the logic to configure volume with scsi controller

This commit is fixing the issue by adding the address element to the
volumes configuration.

Closes-Bug: #1686116
Change-Id: I701145abc0e300711a01889e8d62b1f7887da120
This commit is contained in:
Sahid Orentino Ferdjaoui 2017-04-25 08:04:26 -04:00
parent fb343c4022
commit c25629f85f
3 changed files with 32 additions and 1 deletions

View File

@ -3516,7 +3516,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
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)
conn_info = {'driver_volume_type': 'fake'}
bdms = block_device_obj.block_device_make_list_from_dicts(
@ -3549,10 +3550,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(cfg.devices[2].target_dev, 'sdc')
self.assertEqual(cfg.devices[2].target_bus, 'scsi')
self.assertEqual(2, cfg.devices[2].device_addr.unit)
self.assertIsInstance(cfg.devices[3],
vconfig.LibvirtConfigGuestDisk)
self.assertEqual(cfg.devices[3].target_dev, 'sdd')
self.assertEqual(cfg.devices[3].target_bus, 'scsi')
self.assertEqual(3, cfg.devices[3].device_addr.unit)
self.assertIsInstance(cfg.devices[4],
vconfig.LibvirtConfigGuestController)
self.assertEqual(cfg.devices[4].model, 'virtio-scsi')

View File

@ -1047,6 +1047,17 @@ class LibvirtDriver(driver.ComputeDriver):
for source in tcp_devices:
yield (source.get("host"), int(source.get("service")))
def _get_scsi_controller_max_unit(self, guest):
"""Returns the max disk unit used by scsi controller"""
xml = guest.get_xml_desc()
tree = etree.fromstring(xml)
addrs = "./devices/disk[@device='disk']/address[@type='drive']"
ret = []
for obj in tree.findall(addrs):
ret.append(int(obj.get('unit', 0)))
return max(ret)
@staticmethod
def _get_rbd_driver():
return rbd_utils.RBDDriver(
@ -1213,6 +1224,9 @@ class LibvirtDriver(driver.ComputeDriver):
disk_info = blockinfo.get_info_from_bdm(
instance, CONF.libvirt.virt_type, instance.image_meta, bdm)
self._connect_volume(connection_info, disk_info, instance)
if disk_info['bus'] == 'scsi':
disk_info['unit'] = self._get_scsi_controller_max_unit(guest) + 1
conf = self._get_volume_config(connection_info, disk_info)
self._set_cache_mode(conf)
@ -3726,6 +3740,9 @@ class LibvirtDriver(driver.ComputeDriver):
vol_dev = block_device.prepend_dev(vol['mount_device'])
info = disk_mapping[vol_dev]
self._connect_volume(connection_info, info, instance)
if scsi_controller and scsi_controller.model == 'virtio-scsi':
info['unit'] = disk_mapping['unit']
disk_mapping['unit'] += 1
cfg = self._get_volume_config(connection_info, info)
devices.append(cfg)
vol['connection_info'] = connection_info

View File

@ -93,6 +93,17 @@ class LibvirtBaseVolumeDriver(object):
if data.get('discard', False) is True:
conf.driver_discard = 'unmap'
if disk_info['bus'] == 'scsi':
# The driver is responsible to create the SCSI controller
# at index 0.
conf.device_addr = vconfig.LibvirtConfigGuestDeviceAddressDrive()
conf.device_addr.controller = 0
if 'unit' in disk_info:
# In order to allow up to 256 disks handled by one
# virtio-scsi controller, the device addr should be
# specified.
conf.device_addr.unit = disk_info['unit']
return conf
def connect_volume(self, connection_info, disk_info, instance):