libvirt: update logic to configure device for scsi controller
When using virtio-scsi it is possible to handle up to 256 disk but
because we do not specifically set the information about the
controller only 6 can be handled.
This commit is fixing the issue by adding the address element to the
disk configuration.
Conflicts:
nova/virt/libvirt/driver.py
Closes-Bug: #1686116
Change-Id: I98e53b378cc99747765066001a0b51880543d2dd
(cherry picked from commit fb343c4022
)
This commit is contained in:
parent
34a0ade4cc
commit
70ede864e7
|
@ -198,7 +198,8 @@ class ImageBackendFixture(fixtures.Fixture):
|
||||||
self.imported_files.append((local_filename, remote_filename))
|
self.imported_files.append((local_filename, remote_filename))
|
||||||
|
|
||||||
def _fake_libvirt_info(self, mock_disk, disk_bus, disk_dev, device_type,
|
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
|
# For tests in test_virt_drivers which expect libvirt_info to be
|
||||||
# functional
|
# functional
|
||||||
info = config.LibvirtConfigGuestDisk()
|
info = config.LibvirtConfigGuestDisk()
|
||||||
|
|
|
@ -3423,12 +3423,24 @@ class LibvirtConnTestCase(test.NoDBTestCase):
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
self.assertEqual(cfg.devices[2].target_dev, disk)
|
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)
|
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
|
|
||||||
image_meta = objects.ImageMeta.from_dict({
|
image_meta = objects.ImageMeta.from_dict({
|
||||||
"disk_format": "raw",
|
"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)
|
instance_ref = objects.Instance(**self.test_instance)
|
||||||
|
|
||||||
disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
|
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)
|
cfg = drvr._get_guest_config(instance_ref, [], image_meta, disk_info)
|
||||||
self.assertIsInstance(cfg.devices[0],
|
self.assertIsInstance(cfg.devices[0],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
|
self.assertEqual(0, cfg.devices[0].device_addr.unit)
|
||||||
self.assertIsInstance(cfg.devices[1],
|
self.assertIsInstance(cfg.devices[1],
|
||||||
vconfig.LibvirtConfigGuestDisk)
|
vconfig.LibvirtConfigGuestDisk)
|
||||||
|
self.assertEqual(1, cfg.devices[1].device_addr.unit)
|
||||||
self.assertIsInstance(cfg.devices[2],
|
self.assertIsInstance(cfg.devices[2],
|
||||||
vconfig.LibvirtConfigGuestController)
|
vconfig.LibvirtConfigGuestController)
|
||||||
self.assertEqual(cfg.devices[2].model, 'virtio-scsi')
|
self.assertEqual(cfg.devices[2].model, 'virtio-scsi')
|
||||||
|
|
|
@ -3536,6 +3536,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
{'qemu': MIN_QEMU_DISCARD_VERSION})
|
{'qemu': MIN_QEMU_DISCARD_VERSION})
|
||||||
raise exception.Invalid(msg)
|
raise exception.Invalid(msg)
|
||||||
|
|
||||||
|
disk_unit = None
|
||||||
disk = self.image_backend.by_name(instance, name, image_type)
|
disk = self.image_backend.by_name(instance, name, image_type)
|
||||||
if (name == 'disk.config' and image_type == 'rbd' and
|
if (name == 'disk.config' and image_type == 'rbd' and
|
||||||
not disk.exists()):
|
not disk.exists()):
|
||||||
|
@ -3551,12 +3552,17 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
LOG.debug('Config drive not found in RBD, falling back to the '
|
LOG.debug('Config drive not found in RBD, falling back to the '
|
||||||
'instance directory', instance=instance)
|
'instance directory', instance=instance)
|
||||||
disk_info = disk_mapping[name]
|
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['dev'],
|
||||||
disk_info['type'],
|
disk_info['type'],
|
||||||
self.disk_cachemode,
|
self.disk_cachemode,
|
||||||
inst_type['extra_specs'],
|
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):
|
def _get_guest_fs_config(self, instance, name, image_type=None):
|
||||||
disk = self.image_backend.by_name(instance, name, image_type)
|
disk = self.image_backend.by_name(instance, name, image_type)
|
||||||
|
@ -3574,6 +3580,19 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
mount_rootfs = CONF.libvirt.virt_type == "lxc"
|
mount_rootfs = CONF.libvirt.virt_type == "lxc"
|
||||||
scsi_controller = self._get_scsi_controller(image_meta)
|
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():
|
def _get_ephemeral_devices():
|
||||||
eph_devices = []
|
eph_devices = []
|
||||||
for idx, eph in enumerate(
|
for idx, eph in enumerate(
|
||||||
|
@ -3683,6 +3702,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
scsi_controller = vconfig.LibvirtConfigGuestController()
|
scsi_controller = vconfig.LibvirtConfigGuestController()
|
||||||
scsi_controller.type = 'scsi'
|
scsi_controller.type = 'scsi'
|
||||||
scsi_controller.model = hw_scsi_model
|
scsi_controller.model = hw_scsi_model
|
||||||
|
scsi_controller.index = 0
|
||||||
return scsi_controller
|
return scsi_controller
|
||||||
|
|
||||||
def _get_host_sysinfo_serial_hardware(self):
|
def _get_host_sysinfo_serial_hardware(self):
|
||||||
|
|
|
@ -118,7 +118,8 @@ class Image(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def libvirt_info(self, disk_bus, disk_dev, device_type, cache_mode,
|
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.
|
"""Get `LibvirtConfigGuestDisk` filled for this image.
|
||||||
|
|
||||||
:disk_dev: Disk bus device name
|
:disk_dev: Disk bus device name
|
||||||
|
@ -144,10 +145,24 @@ class Image(object):
|
||||||
info.source_path = self.path
|
info.source_path = self.path
|
||||||
info.boot_order = boot_order
|
info.boot_order = boot_order
|
||||||
|
|
||||||
|
if disk_bus == 'scsi':
|
||||||
|
self.disk_scsi(info, disk_unit)
|
||||||
|
|
||||||
self.disk_qos(info, extra_specs)
|
self.disk_qos(info, extra_specs)
|
||||||
|
|
||||||
return info
|
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):
|
def disk_qos(self, info, extra_specs):
|
||||||
tune_items = ['disk_read_bytes_sec', 'disk_read_iops_sec',
|
tune_items = ['disk_read_bytes_sec', 'disk_read_iops_sec',
|
||||||
'disk_write_bytes_sec', 'disk_write_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
|
self.discard_mode = CONF.libvirt.hw_disk_discard
|
||||||
|
|
||||||
def libvirt_info(self, disk_bus, disk_dev, device_type, cache_mode,
|
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.
|
"""Get `LibvirtConfigGuestDisk` filled for this image.
|
||||||
|
|
||||||
:disk_dev: Disk bus device name
|
:disk_dev: Disk bus device name
|
||||||
|
@ -833,6 +849,9 @@ class Rbd(Image):
|
||||||
info.auth_secret_type = 'ceph'
|
info.auth_secret_type = 'ceph'
|
||||||
info.auth_secret_uuid = CONF.libvirt.rbd_secret_uuid
|
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)
|
self.disk_qos(info, extra_specs)
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
Loading…
Reference in New Issue