Merge "libvirt: add configuration option for volume AIO mode"

This commit is contained in:
Zuul
2025-12-05 05:20:30 +00:00
committed by Gerrit Code Review
8 changed files with 75 additions and 3 deletions

View File

@@ -1652,6 +1652,15 @@ Possible values are:
accessed by anyone else. The Libvirt secret is public and persistent. It
can be read by anyone with sufficient access on the host. The instance can
be live-migrated and automatically resumed after host reboot.
"""),
cfg.BoolOpt(
'use_default_aio_mode_for_volumes',
default=False,
help="""
With the NFS, FC, and iSCSI Cinder volume backends, Nova explicitly sets AIO
mode ``io=native`` in the Libvirt guest XML. Operators may set this option to
True in order to defer AIO mode selection to QEMU if forcing ``io=native`` is
not desired.
"""),
]

View File

@@ -65,6 +65,22 @@ class LibvirtFibreChannelVolumeDriverTestCase(
self.assertEqual('raw', tree.find('./driver').get('type'))
self.assertEqual('native', tree.find('./driver').get('io'))
def test_libvirt_fibrechan_driver_get_config_default_aio_mode(self):
self.flags(use_default_aio_mode_for_volumes=True, group='libvirt')
libvirt_driver = fibrechannel.LibvirtFibreChannelVolumeDriver(
self.fake_host)
device_path = '/dev/fake-dev'
connection_info = {'data': {'device_path': device_path}}
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self.assertEqual('block', tree.get('type'))
self.assertEqual(device_path, tree.find('./source').get('dev'))
self.assertEqual('raw', tree.find('./driver').get('type'))
self.assertIsNone(tree.find('./driver').get('io'))
def test_extend_volume(self):
device_path = '/dev/fake-dev'
connection_info = {'data': {'device_path': device_path}}

View File

@@ -45,6 +45,22 @@ class LibvirtISCSIVolumeDriverTestCase(
self.assertEqual('raw', tree.find('./driver').get('type'))
self.assertEqual('native', tree.find('./driver').get('io'))
def test_libvirt_iscsi_driver_get_config_default_aio_mode(self):
self.flags(use_default_aio_mode_for_volumes=True, group='libvirt')
libvirt_driver = iscsi.LibvirtISCSIVolumeDriver(self.fake_host)
device_path = '/dev/fake-dev'
connection_info = {'data': {'device_path': device_path}}
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self.assertEqual('block', tree.get('type'))
self.assertEqual(device_path, tree.find('./source').get('dev'))
self.assertEqual('raw', tree.find('./driver').get('type'))
self.assertIsNone(tree.find('./driver').get('io'))
@mock.patch.object(iscsi.LOG, 'warning')
def test_libvirt_iscsi_driver_disconnect_volume_with_devicenotfound(self,
mock_LOG_warning):

View File

@@ -77,6 +77,24 @@ class LibvirtNFSVolumeDriverTestCase(test_volume.LibvirtVolumeBaseTestCase):
self.assertEqual('raw', tree.find('./driver').get('type'))
self.assertEqual('native', tree.find('./driver').get('io'))
def test_libvirt_nfs_driver_get_config_default_aio_mode(self):
self.flags(use_default_aio_mode_for_volumes=True, group='libvirt')
libvirt_driver = nfs.LibvirtNFSVolumeDriver(self.fake_host)
export_string = '192.168.1.1:/nfs/share1'
export_mnt_base = os.path.join(self.mnt_base,
utils.get_hash_str(export_string))
file_path = os.path.join(export_mnt_base, self.name)
connection_info = {'data': {'export': export_string,
'name': self.name,
'device_path': file_path}}
conf = libvirt_driver.get_config(connection_info, self.disk_info)
tree = conf.format_dom()
self._assertFileTypeEquals(tree, file_path)
self.assertEqual('raw', tree.find('./driver').get('type'))
self.assertIsNone(tree.find('./driver').get('io'))
def test_libvirt_nfs_driver_with_opts(self):
libvirt_driver = nfs.LibvirtNFSVolumeDriver(self.fake_host)
export_string = '192.168.1.1:/nfs/share1'

View File

@@ -45,7 +45,8 @@ class LibvirtFibreChannelVolumeDriver(libvirt_volume.LibvirtBaseVolumeDriver):
conf.source_type = "block"
conf.source_path = connection_info['data']['device_path']
conf.driver_io = "native"
if not CONF.libvirt.use_default_aio_mode_for_volumes:
conf.driver_io = "native"
return conf
def connect_volume(self, connection_info, instance):

View File

@@ -55,7 +55,8 @@ class LibvirtISCSIVolumeDriver(libvirt_volume.LibvirtBaseVolumeDriver):
self).get_config(connection_info, disk_info)
conf.source_type = "block"
conf.source_path = connection_info['data']['device_path']
conf.driver_io = "native"
if not CONF.libvirt.use_default_aio_mode_for_volumes:
conf.driver_io = "native"
return conf
def connect_volume(self, connection_info, instance):

View File

@@ -34,7 +34,8 @@ class LibvirtNFSVolumeDriver(fs.LibvirtMountedFileSystemVolumeDriver):
conf.source_type = 'file'
conf.source_path = connection_info['data']['device_path']
conf.driver_format = connection_info['data'].get('format', 'raw')
conf.driver_io = "native"
if not CONF.libvirt.use_default_aio_mode_for_volumes:
conf.driver_io = "native"
return conf
def _mount_options(self, connection_info):

View File

@@ -0,0 +1,10 @@
features:
- |
A new configuration option ``[libvirt]use_default_aio_mode_for_volumes``
has been added to enable use of QEMU default AIO modes for NFS, FC, and
iSCSI Cinder volumes.
By default, Nova explicitly sets AIO mode ``io=native`` in the Libvirt
guest XML for NFS, FC, and iSCSI Cinder volumes. Operators may set this
option to ``True`` in order to defer AIO mode selection to QEMU if forcing
``io=native`` is not desired.