libvirt: fix disk I/O QOS support with RBD

The disk I/O QOS settings were set in the libvirt_info
method of the Image class. While this is fine for most
subclasses, the Rbd subclass overrides this method and
so was loosing the QOS settings. Move the setting of
QOS parameters into a separate method so it can be
called in all places that need it. For added fun the
commit 86e6f34 which added QOS settings originally never
added any unit tests to cover its operation.

Co-authored: Daniel P. Berrange <berrange@redhat.com>
Fixes bug #1405367
Change-Id: Ibb3a4dff8996c29ef921be7c56648a442bbb89a2
This commit is contained in:
StephenSun 2014-12-25 12:04:03 +08:00 committed by Daniel P. Berrange
parent 0142fc20f1
commit fdb7b030ab
2 changed files with 49 additions and 1 deletions

View File

@ -153,6 +153,37 @@ class _ImageTestCase(object):
self.assertEqual(fs.source_type, "file")
self.assertEqual(fs.source_file, image.path)
def test_libvirt_info(self):
image = self.image_class(self.INSTANCE, self.NAME)
extra_specs = {
'quota:disk_read_bytes_sec': 10 * units.Mi,
'quota:disk_read_iops_sec': 1 * units.Ki,
'quota:disk_write_bytes_sec': 20 * units.Mi,
'quota:disk_write_iops_sec': 2 * units.Ki,
'quota:disk_total_bytes_sec': 30 * units.Mi,
'quota:disk_total_iops_sec': 3 * units.Ki,
}
disk = image.libvirt_info(disk_bus="virtio",
disk_dev="/dev/vda",
device_type="cdrom",
cache_mode="none",
extra_specs=extra_specs,
hypervisor_version=4004001)
self.assertIsInstance(disk, vconfig.LibvirtConfigGuestDisk)
self.assertEqual("/dev/vda", disk.target_dev)
self.assertEqual("virtio", disk.target_bus)
self.assertEqual("none", disk.driver_cache)
self.assertEqual("cdrom", disk.source_device)
self.assertEqual(10 * units.Mi, disk.disk_read_bytes_sec)
self.assertEqual(1 * units.Ki, disk.disk_read_iops_sec)
self.assertEqual(20 * units.Mi, disk.disk_write_bytes_sec)
self.assertEqual(2 * units.Ki, disk.disk_write_iops_sec)
self.assertEqual(30 * units.Mi, disk.disk_total_bytes_sec)
self.assertEqual(3 * units.Ki, disk.disk_total_iops_sec)
@mock.patch('nova.virt.disk.api.get_disk_size')
def test_get_disk_size(self, get_disk_size):
get_disk_size.return_value = 2361393152
@ -1336,6 +1367,16 @@ class RbdTestCase(_ImageTestCase, test.NoDBTestCase):
self.TEMPLATE_PATH, 1)
driver_mock.size.assert_called_once_with(image.rbd_name)
@mock.patch.object(rbd_utils.RBDDriver, "get_mon_addrs")
def test_libvirt_info(self, mock_mon_addrs):
def get_mon_addrs():
hosts = ["server1", "server2"]
ports = ["1899", "1920"]
return hosts, ports
mock_mon_addrs.side_effect = get_mon_addrs
super(RbdTestCase, self).test_libvirt_info()
@mock.patch.object(rbd_utils.RBDDriver, "get_mon_addrs")
def test_get_model(self, mock_mon_addrs):
pool = "FakePool"

View File

@ -165,6 +165,11 @@ class Image(object):
info.driver_name = driver_name
info.source_path = self.path
self.disk_qos(info, extra_specs)
return info
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',
'disk_total_bytes_sec', 'disk_total_iops_sec']
@ -173,7 +178,6 @@ class Image(object):
if len(scope) > 1 and scope[0] == 'quota':
if scope[1] in tune_items:
setattr(info, scope[1], value)
return info
def libvirt_fs_info(self, target, driver_type=None):
"""Get `LibvirtConfigGuestFilesys` filled for this image.
@ -729,6 +733,9 @@ class Rbd(Image):
if auth_enabled:
info.auth_secret_type = 'ceph'
info.auth_secret_uuid = CONF.libvirt.rbd_secret_uuid
self.disk_qos(info, extra_specs)
return info
def _can_fallocate(self):