Add enhanced KVM storage QoS quotas
This will add additonal KVM-based qoutas for Cinder front-end QoS The new quotas are: - read_bytes_sec_max - write_bytes_sec_max - total_bytes_sec_max - read_iops_sec_max - write_iops_sec_max - total_iops_sec_max - size_iops_sec Depends-On: https://review.openstack.org/574804 Change-Id: I5a8f34c7ed3dea940700dffd54bc7d44f7518ab4 Implements: blueprint enhanced-kvm-storage-qos
This commit is contained in:
parent
0a642e2eee
commit
37aea88845
@ -1016,12 +1016,22 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
|
||||
obj.source_path = "/tmp/hello"
|
||||
obj.target_dev = "/dev/hda"
|
||||
obj.target_bus = "ide"
|
||||
# Note that read/write iops/bytes values cannot be used with
|
||||
# total values. These are only here for illustrative purposes.
|
||||
obj.disk_read_bytes_sec = 1024000
|
||||
obj.disk_read_iops_sec = 1000
|
||||
obj.disk_total_bytes_sec = 2048000
|
||||
obj.disk_write_bytes_sec = 1024000
|
||||
obj.disk_write_iops_sec = 1000
|
||||
obj.disk_total_iops_sec = 2000
|
||||
obj.disk_write_bytes_sec_max = 1536000
|
||||
obj.disk_write_iops_sec_max = 1500
|
||||
obj.disk_total_iops_sec_max = 3072000
|
||||
obj.disk_read_bytes_sec_max = 1536000
|
||||
obj.disk_read_iops_sec_max = 1500
|
||||
obj.disk_total_iops_sec_max = 2000
|
||||
obj.disk_total_bytes_sec_max = 3072000
|
||||
obj.disk_size_iops_sec = 16
|
||||
|
||||
xml = obj.to_xml()
|
||||
self.assertXmlEqual(xml, """
|
||||
@ -1035,6 +1045,13 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
|
||||
<write_iops_sec>1000</write_iops_sec>
|
||||
<total_bytes_sec>2048000</total_bytes_sec>
|
||||
<total_iops_sec>2000</total_iops_sec>
|
||||
<read_bytes_sec_max>1536000</read_bytes_sec_max>
|
||||
<write_bytes_sec_max>1536000</write_bytes_sec_max>
|
||||
<total_bytes_sec_max>3072000</total_bytes_sec_max>
|
||||
<read_iops_sec_max>1500</read_iops_sec_max>
|
||||
<write_iops_sec_max>1500</write_iops_sec_max>
|
||||
<total_iops_sec_max>2000</total_iops_sec_max>
|
||||
<size_iops_sec>16</size_iops_sec>
|
||||
</iotune>
|
||||
</disk>""")
|
||||
|
||||
|
@ -118,8 +118,18 @@ class LibvirtISCSIVolumeBaseTestCase(LibvirtVolumeBaseTestCase):
|
||||
'target_lun': 1,
|
||||
'device_path': dev_path,
|
||||
'qos_specs': {
|
||||
# Note that read/write iops/bytes values cannot
|
||||
# be used with total values.
|
||||
# These are only here for illustrative purposes.
|
||||
'total_bytes_sec': '102400',
|
||||
'read_iops_sec': '200',
|
||||
'read_bytes_sec_max': '150000',
|
||||
'read_iops_sec_max': '2000',
|
||||
'write_bytes_sec_max': '250000',
|
||||
'write_iops_sec_max': '3000',
|
||||
'total_bytes_sec_max': '400000',
|
||||
'total_iops_sec_max': '4000',
|
||||
'size_iops_sec': '16',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -707,6 +707,13 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
|
||||
self.disk_write_iops_sec = None
|
||||
self.disk_total_bytes_sec = None
|
||||
self.disk_total_iops_sec = None
|
||||
self.disk_read_bytes_sec_max = None
|
||||
self.disk_write_bytes_sec_max = None
|
||||
self.disk_total_bytes_sec_max = None
|
||||
self.disk_read_iops_sec_max = None
|
||||
self.disk_write_iops_sec_max = None
|
||||
self.disk_total_iops_sec_max = None
|
||||
self.disk_size_iops_sec = None
|
||||
self.logical_block_size = None
|
||||
self.physical_block_size = None
|
||||
self.readonly = False
|
||||
@ -718,6 +725,64 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
|
||||
self.mirror = None
|
||||
self.encryption = None
|
||||
|
||||
def _format_iotune(self, dev):
|
||||
iotune = etree.Element("iotune")
|
||||
|
||||
if self.disk_read_bytes_sec is not None:
|
||||
iotune.append(self._text_node("read_bytes_sec",
|
||||
self.disk_read_bytes_sec))
|
||||
|
||||
if self.disk_read_iops_sec is not None:
|
||||
iotune.append(self._text_node("read_iops_sec",
|
||||
self.disk_read_iops_sec))
|
||||
|
||||
if self.disk_write_bytes_sec is not None:
|
||||
iotune.append(self._text_node("write_bytes_sec",
|
||||
self.disk_write_bytes_sec))
|
||||
|
||||
if self.disk_write_iops_sec is not None:
|
||||
iotune.append(self._text_node("write_iops_sec",
|
||||
self.disk_write_iops_sec))
|
||||
|
||||
if self.disk_total_bytes_sec is not None:
|
||||
iotune.append(self._text_node("total_bytes_sec",
|
||||
self.disk_total_bytes_sec))
|
||||
|
||||
if self.disk_total_iops_sec is not None:
|
||||
iotune.append(self._text_node("total_iops_sec",
|
||||
self.disk_total_iops_sec))
|
||||
|
||||
if self.disk_read_bytes_sec_max is not None:
|
||||
iotune.append(self._text_node("read_bytes_sec_max",
|
||||
self.disk_read_bytes_sec_max))
|
||||
|
||||
if self.disk_write_bytes_sec_max is not None:
|
||||
iotune.append(self._text_node("write_bytes_sec_max",
|
||||
self.disk_write_bytes_sec_max))
|
||||
|
||||
if self.disk_total_bytes_sec_max is not None:
|
||||
iotune.append(self._text_node("total_bytes_sec_max",
|
||||
self.disk_total_bytes_sec_max))
|
||||
|
||||
if self.disk_read_iops_sec_max is not None:
|
||||
iotune.append(self._text_node("read_iops_sec_max",
|
||||
self.disk_read_iops_sec_max))
|
||||
|
||||
if self.disk_write_iops_sec_max is not None:
|
||||
iotune.append(self._text_node("write_iops_sec_max",
|
||||
self.disk_write_iops_sec_max))
|
||||
|
||||
if self.disk_total_iops_sec_max is not None:
|
||||
iotune.append(self._text_node("total_iops_sec_max",
|
||||
self.disk_total_iops_sec_max))
|
||||
|
||||
if self.disk_size_iops_sec is not None:
|
||||
iotune.append(self._text_node("size_iops_sec",
|
||||
self.disk_size_iops_sec))
|
||||
|
||||
if len(iotune) > 0:
|
||||
dev.append(iotune)
|
||||
|
||||
def format_dom(self):
|
||||
dev = super(LibvirtConfigGuestDisk, self).format_dom()
|
||||
|
||||
@ -774,34 +839,7 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
|
||||
if self.serial is not None:
|
||||
dev.append(self._text_node("serial", self.serial))
|
||||
|
||||
iotune = etree.Element("iotune")
|
||||
|
||||
if self.disk_read_bytes_sec is not None:
|
||||
iotune.append(self._text_node("read_bytes_sec",
|
||||
self.disk_read_bytes_sec))
|
||||
|
||||
if self.disk_read_iops_sec is not None:
|
||||
iotune.append(self._text_node("read_iops_sec",
|
||||
self.disk_read_iops_sec))
|
||||
|
||||
if self.disk_write_bytes_sec is not None:
|
||||
iotune.append(self._text_node("write_bytes_sec",
|
||||
self.disk_write_bytes_sec))
|
||||
|
||||
if self.disk_write_iops_sec is not None:
|
||||
iotune.append(self._text_node("write_iops_sec",
|
||||
self.disk_write_iops_sec))
|
||||
|
||||
if self.disk_total_bytes_sec is not None:
|
||||
iotune.append(self._text_node("total_bytes_sec",
|
||||
self.disk_total_bytes_sec))
|
||||
|
||||
if self.disk_total_iops_sec is not None:
|
||||
iotune.append(self._text_node("total_iops_sec",
|
||||
self.disk_total_iops_sec))
|
||||
|
||||
if len(iotune) > 0:
|
||||
dev.append(iotune)
|
||||
self._format_iotune(dev)
|
||||
|
||||
# Block size tuning
|
||||
if (self.logical_block_size is not None or
|
||||
|
@ -63,7 +63,11 @@ class LibvirtBaseVolumeDriver(object):
|
||||
if 'qos_specs' in data and data['qos_specs']:
|
||||
tune_opts = ['total_bytes_sec', 'read_bytes_sec',
|
||||
'write_bytes_sec', 'total_iops_sec',
|
||||
'read_iops_sec', 'write_iops_sec']
|
||||
'read_iops_sec', 'write_iops_sec',
|
||||
'read_bytes_sec_max', 'read_iops_sec_max',
|
||||
'write_bytes_sec_max', 'write_iops_sec_max',
|
||||
'total_bytes_sec_max', 'total_iops_sec_max',
|
||||
'size_iops_sec']
|
||||
specs = data['qos_specs']
|
||||
if isinstance(specs, dict):
|
||||
for k, v in specs.items():
|
||||
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The libvirt driver now supports additional Cinder front-end
|
||||
QoS specs, allowing the specification of additional IO
|
||||
burst limits applied for each attached disk, individually.
|
||||
|
||||
- quota:read_bytes_sec_max
|
||||
- quota:write_bytes_sec_max
|
||||
- quota:total_bytes_sec_max
|
||||
- quota:read_iops_sec_max
|
||||
- quota:write_iops_sec_max
|
||||
- quota:total_iops_sec_max
|
||||
- quota:size_iops_sec
|
||||
|
||||
For more information, see the Cinder admin guide:
|
||||
|
||||
https://docs.openstack.org/cinder/latest/admin/blockstorage-basic-volume-qos.html
|
Loading…
x
Reference in New Issue
Block a user