Royce Lv has uploaded a new change for review.
Change subject: add verb for vdsm to tuneCpu params
......................................................................
add verb for vdsm to tuneCpu params
Engine and Mom need an interface to cap the max cpu and share.
So add this verb to vdsm.
tuneCpu:
Dynamically tune cpu absolute max proportion and relative share.
Input:
vmId: VM to be tuned
max_proportion=<value>: absolute max proportion for each vCPU can consume
-1:no limit,[0.001,1]:valid proportion
relative_share=<value>:relative share of CPU compared with other VMs
output:
success: return doneCode
failure: return errCode tunecpuErr.
Change-Id: I09e02e09ef06ad6de45be75c3f2f913a3025750f
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/define.py
M vdsm/libvirtvm.py
M vdsm/storage/misc.py
M vdsm_cli/vdsClient.py
6 files changed, 97 insertions(+), 8 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/92/7492/1
diff --git a/vdsm/API.py b/vdsm/API.py
index 827f73b..f0c47d1 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -26,6 +26,7 @@
import time
import threading
import logging
+import math
from vdsm import utils
from clientIF import clientIF
@@ -37,6 +38,7 @@
import storage.volume
import storage.sd
import storage.image
+import storage.storage_exception as se
from vdsm.define import doneCode, errCode, Kbytes, Mbytes
import caps
from vdsm.config import config
@@ -555,6 +557,33 @@
message = USER_SHUTDOWN_MESSAGE
return v.shutdown(delay, message)
+ def tuneCpu(self, tuneParams):
+ try:
+ v = self._cif.vmContainer[self._UUID]
+ if 'relative_share' in tuneParams:
+ tuneParams['cpu_shares'] = storage.misc.validateN(
+ tuneParams['relative_share'], 'relative_share')
+ del(tuneParams['relative_share'])
+ if 'max_proportion' in tuneParams:
+ max = storage.misc.validateFloat(
+ tuneParams['max_proportion'], 'max_proportion')
+ tuneParams['vcpu_period'] = 1000000
+ if max > 1:
+ raise se.InvalidParameterException('max_proportion', max)
+ elif max >= 0.001:
+ tuneParams['vcpu_quota'] = int(
+ round(tuneParams['vcpu_period'] * max))
+ else:
+ tuneParams['vcpu_quota'] = int(math.floor(max))
+ del(tuneParams['max_proportion'])
+ del(tuneParams['vmId'])
+ except KeyError:
+ return errCode['noVM']
+ except se.InvalidParameterException:
+ return errCode['tunecpuErr']
+
+ return v.tuneCpu(tuneParams)
+
def _createSysprepFloppyFromInf(self, infFileBinary, floppyImage):
try:
rc, out, err = utils.execCmd([constants.EXT_MK_SYSPREP_FLOPPY,
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 826c125..37b1f60 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -265,6 +265,10 @@
vm = API.VM(vmId)
return vm.snapshot(snapDrives)
+ def vmTuneCpu(self, params):
+ vm = API.VM(params['vmId'])
+ return vm.tuneCpu(params)
+
def vmMerge(self, vmId, mergeDrives):
vm = API.VM(vmId)
return vm.merge(mergeDrives)
@@ -765,7 +769,8 @@
(self.vmHotplugDisk, 'hotplugDisk'),
(self.vmHotunplugDisk, 'hotunplugDisk'),
(self.vmHotplugNic, 'hotplugNic'),
- (self.vmHotunplugNic, 'hotunplugNic'))
+ (self.vmHotunplugNic, 'hotunplugNic'),
+ (self.vmTuneCpu, 'tuneCpu'))
def getIrsMethods(self):
return ((self.domainActivate, 'activateStorageDomain'),
diff --git a/vdsm/define.py b/vdsm/define.py
index 049d36c..d41d467 100644
--- a/vdsm/define.py
+++ b/vdsm/define.py
@@ -117,6 +117,9 @@
'momErr': {'status':
{'code': 54,
'message': 'Failed to set mom policy'}},
+ 'tunecpuErr': {'status':
+ {'code': 55,
+ 'message': 'Failed to Tune CPU'}},
'recovery': {'status':
{'code': 99,
'message':
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index e95e94b..59c7ec6 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -1371,13 +1371,17 @@
if self._initTimePauseCode == 'ENOSPC':
self.cont()
self.conf['pid'] = self._getPid()
-
- nice = int(self.conf.get('nice', '0'))
- nice = max(min(nice, 19), 0)
- try:
- self._dom.setSchedulerParameters({'cpu_shares': (20 - nice) * 51})
- except:
- self.log.warning('failed to set Vm niceness', exc_info=True)
+ #do not trying to change cpu_shares for recovery and restore flows
+ if not 'recover' in self.conf and not 'restoreState' in
self.conf:
+ nice = int(self.conf.get('nice', '0'))
+ nice = max(min(nice, 19), 0)
+ cpuShare = (20 - nice) * 51
+ try:
+ self._dom.setSchedulerParameters({'cpu_shares': cpuShare})
+ except:
+ self.log.warning('failed to set Vm niceness', exc_info=True)
+ self.conf['cpu_shares'] = cpuShare
+ self.saveState()
def _run(self):
self.log.info("VM wrapper has started")
@@ -1931,6 +1935,23 @@
(snapFlags & libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE
== libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE)}
+ def tuneCpu(self, tuneParams):
+ try:
+ self._dom.setSchedulerParameters(tuneParams)
+ self.conf['cpu_shares'] = tuneParams.get('cpu_shares')
+ self.conf['vcpu_quota'] = tuneParams.get('vcpu_quota')
+ self.conf['vcpu_period'] = tuneParams.get('vcpu_period')
+ self.saveState()
+ return {'status': doneCode}
+ except libvirt.libvirtError, e:
+ self.log.error("TuneCpu failed:%s",
+ e.message, exc_info=True)
+ return errCode['tunecpuErr']
+ except LookupError:
+ self.log.error('TuneCpu failed: unrecongnized params',
+ exc_info=True)
+ return errCode['tunecpuErr']
+
def _runMerge(self):
for mergeStatus in self.conf.get('liveMerge', []):
if mergeStatus['status'] != MERGESTATUS.NOT_STARTED:
diff --git a/vdsm/storage/misc.py b/vdsm/storage/misc.py
index 161726b..1f5ed1a 100644
--- a/vdsm/storage/misc.py
+++ b/vdsm/storage/misc.py
@@ -503,6 +503,13 @@
return n
+def validateFloat(floatNumber, name):
+ try:
+ return float(floatNumber)
+ except:
+ raise se.InvalidParameterException(floatNumber, name)
+
+
def rotateFiles(directory, prefixName, gen, cp=False, persist=False):
log.debug("dir: %s, prefixName: %s, versions: %s" %
(directory, prefixName, gen))
diff --git a/vdsm_cli/vdsClient.py b/vdsm_cli/vdsClient.py
index a164c20..ab0fa4c 100644
--- a/vdsm_cli/vdsClient.py
+++ b/vdsm_cli/vdsClient.py
@@ -204,6 +204,18 @@
return self.ExecAndExit(self.s.create(params))
+ def tuneCpu(self, args):
+ params = {}
+ confLines = []
+ params['vmId'] = args[0]
+ if len(args) > 1:
+ confLines.extend(args[1:])
+ for line in confLines:
+ if '=' in line:
+ param, value = line.split("=", 1)
+ params[param] = value
+ return self.ExecAndExit(self.s.tuneCpu(params))
+
def hotplugNic(self, args):
nic = self._parseDriveSpec(args[1])
nic['type'] = 'interface'
@@ -1802,6 +1814,18 @@
'Optional additional parameters in dictionary format,'
' name:value,name:value'
)),
+ 'tuneCpu': (serv.tuneCpu,
+ ('<vmId>'
+ '[max_proportion=value relative_share=value]',
+ 'Parameters list: r=required, o=optional',
+ 'r vmId: The vm to be tuned',
+ 'o max_proportion=<value>: '
+ 'max proportion for each vCPU can be consumed, '
+ '-1 is no limit,[0.001,1] is valid proportion',
+ 'o relative_share=<value>:relative share of CPU'
+ 'compared with other VMs',
+ 'Dynamically tune cpu absolute max proportion and relative
share'
+ )),
'migrate': (serv.do_migrate,
('vmId=<id> method=<offline|online>
src=<host:[port]> '
'dst=<host:[port]>',
--
To view, visit
http://gerrit.ovirt.org/7492
To unsubscribe, visit
http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I09e02e09ef06ad6de45be75c3f2f913a3025750f
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>