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 <akrej...@redhat.com>
---
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 <rm...@redhat.com>
Gerrit-Reviewer: Andrej Krejcir <akrej...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to