Hello Andrej Krejcir,
I'd like you to do a code review. Please visit
https://gerrit.ovirt.org/55820
to review the following change.
Change subject: Apply storage QoS on running VM
......................................................................
Apply storage QoS on running VM
Modified updateVmPolicy command to accept disk ids.
Added a function to get current io tune from libvirt.
Change-Id: I3f5fcb8705c974f1d91c90cdb3158d2e8dd314f8
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1201482
Signed-off-by: Andrej Krejcir <[email protected]>
---
M tests/vmTests.py
M vdsm/API.py
M vdsm/rpc/Bridge.py
M vdsm/rpc/bindingxmlrpc.py
M vdsm/rpc/vdsmapi-schema.json
M vdsm/virt/vm.py
6 files changed, 106 insertions(+), 7 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/20/55820/1
diff --git a/tests/vmTests.py b/tests/vmTests.py
index a0d7d0b..5471c03 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -809,7 +809,7 @@
self.assertEqual(expected_xml, self._xml_sanitizer(dom._metadata))
- def testGetIoTune(self):
+ def testGetIoTunePolicy(self):
with fake.VM() as machine:
dom = fake.Domain()
dom._metadata = """
@@ -842,7 +842,7 @@
u'totalBytes': 9999
}}
]
- self.assertEqual(tunables, expected)
+ self.assertEqual(tunables['ioTunePolicy'], expected)
def testSetIoTune(self):
diff --git a/vdsm/API.py b/vdsm/API.py
index d5f6ced..46c5e66 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -770,6 +770,12 @@
return errCode['noVM']
return v.setCpuTuneQuota(quota)
+ def getIoTune(self):
+ v = self._cif.vmContainer.get(self._UUID)
+ if not v:
+ return errCode['noVM']
+ return v.getIoTune()
+
def setIoTune(self, tunables):
v = self._cif.vmContainer.get(self._UUID)
if not v:
diff --git a/vdsm/rpc/Bridge.py b/vdsm/rpc/Bridge.py
index c2a114c..8815a18 100644
--- a/vdsm/rpc/Bridge.py
+++ b/vdsm/rpc/Bridge.py
@@ -470,6 +470,7 @@
'VM_diskSizeExtend': {'ret': 'size'},
'VM_getDiskAlignment': {'ret': 'alignment'},
'VM_getInfo': {'call': VM_getInfo_Call, 'ret': VM_getInfo_Ret},
+ 'VM_getIoTune': {'ret': 'ioTuneList'},
'VM_getIoTunePolicy': {'ret': 'ioTunePolicyList'},
'VM_getStats': {'ret': 'statsList'},
'VM_hotplugDisk': {'ret': 'vmList'},
diff --git a/vdsm/rpc/bindingxmlrpc.py b/vdsm/rpc/bindingxmlrpc.py
index c521cd8..acb3bbd 100644
--- a/vdsm/rpc/bindingxmlrpc.py
+++ b/vdsm/rpc/bindingxmlrpc.py
@@ -554,6 +554,10 @@
vm = API.VM(vmId)
return vm.getIoTunePolicy()
+ def vmGetIoTune(self, vmId):
+ vm = API.VM(vmId)
+ return vm.getIoTune()
+
def vmSetIoTune(self, vmId, tunables):
vm = API.VM(vmId)
return vm.setIoTune(tunables)
@@ -1108,6 +1112,7 @@
(self.merge, 'merge'),
(self.vmUpdateVmPolicy, 'updateVmPolicy'),
(self.vmSetIoTune, 'setIoTune'),
+ (self.vmGetIoTune, 'getIoTune'),
(self.vmGetIoTunePolicy, 'getIoTunePolicy'),
(self.vmSetCpuTuneQuota, 'vmSetCpuTuneQuota'),
(self.vmSetCpuTunePeriod, 'vmSetCpuTunePeriod'),
diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json
index 8ca7627..cface3b 100644
--- a/vdsm/rpc/vdsmapi-schema.json
+++ b/vdsm/rpc/vdsmapi-schema.json
@@ -2582,10 +2582,19 @@
# @VmDiskDeviceTuneLimits:
#
# Extra parameters for VM disk devices.
+# Either name, path or all 4 IDs must be present
#
# @name: #optional The name of the target device
#
# @path: #optional The path of the target device
+#
+# @domainID: #optional DomainID
+#
+# @poolID: #optional PoolId
+#
+# @imageID: #optional ImageId
+#
+# @volumeID: #optional VolumeId
#
# @guaranteed: IO tune parameters - guaranteed values
#
@@ -2595,6 +2604,8 @@
##
{'type': 'VmDiskDeviceTuneLimits',
'data': {'*name': 'str', '*path': 'str',
+ '*domainID': 'UUID', '*poolID': 'UUID',
+ '*imageID': 'UUID', '*volumeID': 'UUID',
'guaranteed': 'VmDiskDeviceIoTuneParams',
'maximum': 'VmDiskDeviceIoTuneParams'}}
@@ -8705,6 +8716,23 @@
'returns': 'TaskStatus'}
##
+# @VM.getIoTune:
+#
+# Sets the ioTune parameters for block devices
+#
+# @vmID: The UUID of the VM
+#
+# Returns:
+# list of VmDiskDeviceTuneParams objects
+#
+# Since: 4.18.0
+##
+{'command': {'class': 'VM', 'name': 'getIoTune'},
+ 'data': {'vmID': 'UUID'},
+ 'returns': ['VmDiskDeviceTuneParams']}
+
+
+##
# @VM.getIoTunePolicy:
#
# Gets the ioTune policy settings for block devices
@@ -8712,14 +8740,14 @@
# @vmID: The UUID of the VM
#
# Returns:
-# list of VmDiskDeviceTuneParams objects describing
+# list of VmDiskDeviceTuneLimits objects describing
# the current settings
#
# Since: 4.15.0
##
{'command': {'class': 'VM', 'name': 'getIoTunePolicy'},
'data': {'vmID': 'UUID'},
- 'returns': ['VmDiskDeviceTuneParams']}
+ 'returns': ['VmDiskDeviceTuneLimits']}
##
# @VM.setCpuTuneQuota:
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 81c166d..4d0a96d 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -2465,6 +2465,32 @@
self._vcpuLimit = params.pop('vcpuLimit')
if 'ioTune' in params:
+ ioTuneParams = params["ioTune"]
+
+ for ioTune in ioTuneParams:
+ if ("path" in ioTune) or ("name" in ioTune):
+ continue
+
+ self.log.debug("IoTuneParams: %s", str(ioTune))
+
+ try:
+ # All 4 IDs are required to identify a device
+ # If there is a valid reason why not all 4 are required,
+ # please change the code
+
+ disk = self._findDriveByUUIDs({
+ 'domainID': ioTune["domainID"],
+ 'poolID': ioTune["poolID"],
+ 'imageID': ioTune["imageID"],
+ 'volumeID': ioTune["volumeID"]})
+
+ self.log.debug("Device path: %s", disk.path)
+ ioTune["name"] = disk.name
+ ioTune["path"] = disk.path
+
+ except LookupError as e:
+ return response.error('updateVmPolicyErr', e.message)
+
# Make sure the top level element exists
ioTuneList = qos.getElementsByTagName("ioTune")
if not ioTuneList:
@@ -2473,7 +2499,7 @@
qos.appendChild(ioTuneElement)
metadata_modified = True
- if update_io_tune_dom(ioTuneList[0], params["ioTune"]) > 0:
+ if update_io_tune_dom(ioTuneList[0], ioTuneParams) > 0:
metadata_modified = True
del params['ioTune']
@@ -2543,12 +2569,45 @@
qos = self._getVmPolicy()
ioTuneList = qos.getElementsByTagName("ioTune")
if not ioTuneList or not ioTuneList[0].hasChildNodes():
- return []
+ return response.success(ioTunePolicy=[])
for device in ioTuneList[0].getElementsByTagName("device"):
tunables.append(io_tune_dom_to_values(device))
- return tunables
+ return response.success(ioTunePolicy=tunables)
+
+ def getIoTune(self):
+ resultList = []
+
+ for device in self.getDiskDevices():
+ if not isVdsmImage(device):
+ continue
+
+ try:
+ res = self._dom.blockIoTune(
+ device.name,
+ libvirt.VIR_DOMAIN_AFFECT_LIVE)
+
+ # use only certain fields, otherwise
+ # Drive._validateIoTuneParams will not pass
+ ioTune = {k: res[k] for k in (
+ 'total_bytes_sec', 'read_bytes_sec',
+ 'write_bytes_sec', 'total_iops_sec',
+ 'write_iops_sec', 'read_iops_sec')}
+
+ resultList.append({
+ 'name': device.name,
+ 'path': device.path,
+ 'ioTune': ioTune})
+
+ except libvirt.libvirtError as e:
+ self.log.exception("getVmIoTune failed")
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return response.error('noVM')
+ else:
+ return response.error('updateIoTuneErr', e.message)
+
+ return response.success(ioTune=resultList)
def setIoTune(self, tunables):
for io_tune_change in tunables:
--
To view, visit https://gerrit.ovirt.org/55820
To unsubscribe, visit https://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3f5fcb8705c974f1d91c90cdb3158d2e8dd314f8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: ovirt-3.6
Gerrit-Owner: Roman Mohr <[email protected]>
Gerrit-Reviewer: Andrej Krejcir <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches