Change in vdsm[master]: Use more fine lock for hsm.deleteImage().
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: Use more fine lock for hsm.deleteImage().
......................................................................
Use more fine lock for hsm.deleteImage().
When removing an image from a specific SD, lock the image in this
SD exclusively.
Related to: BZ#960952.
Change-Id: Iab04d548610cd86eb70e1fd13a29a3508778cc1d
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/hsm.py
1 file changed, 2 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/13/16413/1
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 5639c13..09c5404 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1437,7 +1437,8 @@
self.getPool(spUUID) # Validates that the pool is connected. WHY?
dom = self.validateSdUUID(sdUUID)
- vars.task.getExclusiveLock(STORAGE, imgUUID)
+ imageResourcesNamespace = sd.getNamespace(sdUUID, IMAGE_NAMESPACE)
+ vars.task.getExclusiveLock(imageResourcesNamespace, imgUUID)
vars.task.getSharedLock(STORAGE, sdUUID)
allVols = dom.getAllVolumes()
volsByImg = sd.getVolsOfImage(allVols, imgUUID)
--
To view, visit http://gerrit.ovirt.org/16413
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iab04d548610cd86eb70e1fd13a29a3508778cc1d
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: [WIP] metaSize calculation as a module function.
by ewarszaw@redhat.com
Eduardo has uploaded a new change for review.
Change subject: [WIP] metaSize calculation as a module function.
......................................................................
[WIP] metaSize calculation as a module function.
Change-Id: If90ba75d11c4962f2e52150e5f381cd93d0e8f35
Signed-off-by: Eduardo <ewarszaw(a)redhat.com>
---
M vdsm/storage/blockSD.py
1 file changed, 23 insertions(+), 23 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/90/11690/1
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index 9b9674e..aa4059a 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -269,6 +269,27 @@
return
+def metaSize(vgName):
+ ''' Calc the minimal meta volume size in MB'''
+ # In any case the metadata volume cannot be less than 512MB for the
+ # case of 512 bytes per volume metadata, 2K for domain metadata and
+ # extent size of 128MB. In any case we compute the right size on line.
+ vg = lvm.getVG(vgName)
+ minmetasize = (SD_METADATA_SIZE / sd.METASIZE * int(vg.extent_size) +
+ (1024 * 1024 - 1)) / (1024 * 1024)
+ metaratio = int(vg.extent_size) / sd.METASIZE
+ metasize = (int(vg.extent_count) * sd.METASIZE +
+ (1024 * 1024 - 1)) / (1024 * 1024)
+ metasize = max(minmetasize, metasize)
+ if metasize > int(vg.free) / (1024 * 1024):
+ raise se.VolumeGroupSizeError("volume group has not enough extents %s"
+ " (Minimum %s), VG may be too small" %
+ (vg.extent_count,
+ (1024 * 1024) / sd.METASIZE))
+ log.info("size %s MB (metaratio %s)" % (metasize, metaratio))
+ return metasize
+
+
class VGTagMetadataRW(object):
log = logging.getLogger("storage.Metadata.VGTagMetadataRW")
METADATA_TAG_PREFIX = "MDT_"
@@ -449,27 +470,6 @@
lvmActivationNamespace)
@classmethod
- def metaSize(cls, vgroup):
- ''' Calc the minimal meta volume size in MB'''
- # In any case the metadata volume cannot be less than 512MB for the
- # case of 512 bytes per volume metadata, 2K for domain metadata and
- # extent size of 128MB. In any case we compute the right size on line.
- vg = lvm.getVG(vgroup)
- minmetasize = (SD_METADATA_SIZE / sd.METASIZE * int(vg.extent_size) +
- (1024 * 1024 - 1)) / (1024 * 1024)
- metaratio = int(vg.extent_size) / sd.METASIZE
- metasize = (int(vg.extent_count) * sd.METASIZE +
- (1024 * 1024 - 1)) / (1024 * 1024)
- metasize = max(minmetasize, metasize)
- if metasize > int(vg.free) / (1024 * 1024):
- raise se.VolumeGroupSizeError(
- "volume group has not enough extents %s (Minimum %s), VG may "
- "be too small" % (vg.extent_count,
- (1024 * 1024) / sd.METASIZE))
- cls.log.info("size %s MB (metaratio %s)" % (metasize, metaratio))
- return metasize
-
- @classmethod
def create(cls, sdUUID, domainName, domClass, vgUUID, storageType,
version):
""" Create new storage domain
@@ -509,7 +509,7 @@
raise se.StorageDomainIsMadeFromTooManyPVs()
# Create metadata service volume
- metasize = cls.metaSize(vgName)
+ metasize = metaSize(vgName)
lvm.createLV(vgName, sd.METADATA, "%s" % (metasize))
# Create the mapping right now so the index 0 is guaranteed
# to belong to the metadata volume. Since the metadata is at
@@ -721,7 +721,7 @@
lvm.extendVG(self.sdUUID, devices, force)
self.updateMapping()
- newsize = self.metaSize(self.sdUUID)
+ newsize = metaSize(self.sdUUID)
lvm.extendLV(self.sdUUID, sd.METADATA, newsize)
def mapMetaOffset(self, vol_name, slotSize):
--
To view, visit http://gerrit.ovirt.org/11690
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If90ba75d11c4962f2e52150e5f381cd93d0e8f35
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Eduardo <ewarszaw(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: image: transform getImageDir into a function
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: image: transform getImageDir into a function
......................................................................
image: transform getImageDir into a function
Change-Id: I8153cb7377d5ea353142647956ff27cda3f63b22
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/blockVolume.py
M vdsm/storage/fileVolume.py
M vdsm/storage/image.py
3 files changed, 8 insertions(+), 10 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/19/26919/1
diff --git a/vdsm/storage/blockVolume.py b/vdsm/storage/blockVolume.py
index d9bbf15..12556d5 100644
--- a/vdsm/storage/blockVolume.py
+++ b/vdsm/storage/blockVolume.py
@@ -412,8 +412,8 @@
"""
Block SD supports lazy image dir creation
"""
- imageDir = image.Image(self.repoPath).getImageDir(self.sdUUID,
- self.imgUUID)
+ imageDir = image.getImagePath(self.repoPath, self.sdUUID,
+ self.imgUUID)
if not os.path.isdir(imageDir):
try:
os.mkdir(imageDir, 0o755)
diff --git a/vdsm/storage/fileVolume.py b/vdsm/storage/fileVolume.py
index f2a93d6..7d7e1ee 100644
--- a/vdsm/storage/fileVolume.py
+++ b/vdsm/storage/fileVolume.py
@@ -482,8 +482,8 @@
In the file volume repositories,
the image dir must exists after creation its first volume.
"""
- imageDir = image.Image(self.repoPath).getImageDir(self.sdUUID,
- self.imgUUID)
+ imageDir = image.getImagePath(self.repoPath, self.sdUUID,
+ self.imgUUID)
if not self.oop.os.path.isdir(imageDir):
raise se.ImagePathError(imageDir)
if not self.oop.os.access(imageDir, os.R_OK | os.W_OK | os.X_OK):
diff --git a/vdsm/storage/image.py b/vdsm/storage/image.py
index 2cf8e7a..0c8232b 100644
--- a/vdsm/storage/image.py
+++ b/vdsm/storage/image.py
@@ -87,6 +87,10 @@
dom.deleteImage(dom.sdUUID, imgUUID, imgVols)
+def getImagePath(repoPath, sdUUID, imgUUID):
+ return os.path.join(repoPath, sdUUID, sd.DOMAIN_IMAGES, imgUUID)
+
+
class Image:
""" Actually represents a whole virtual disk.
Consist from chain of volumes.
@@ -127,12 +131,6 @@
[imageDir]))
os.mkdir(imageDir)
return imageDir
-
- def getImageDir(self, sdUUID, imgUUID):
- """
- Return image directory
- """
- return os.path.join(self.repoPath, sdUUID, sd.DOMAIN_IMAGES, imgUUID)
def deletedVolumeName(self, uuid):
"""
--
To view, visit http://gerrit.ovirt.org/26919
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8153cb7377d5ea353142647956ff27cda3f63b22
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: [WIP]add createVm support of cputune
by lvroyce@linux.vnet.ibm.com
Royce Lv has uploaded a new change for review.
Change subject: [WIP]add createVm support of cputune
......................................................................
[WIP]add createVm support of cputune
allow engine to pass other cputune params through vm create,
createVm now uses nice to config vm share value,
this patch uses 'shares' in vmdef directly (1024 by default)
Change-Id: I76e9b9d291d4801965163774ba45d15b39a77471
Signed-off-by: Royce Lv<lvroyce(a)linux.vnet.ibm.com>
---
M vdsm/libvirtvm.py
1 file changed, 13 insertions(+), 11 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/45/8445/1
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index fd80c69..9b38a36 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -737,10 +737,13 @@
self.dom.appendChild(cpu)
def appendTunable(self):
- #CPU-pinning support
- # see http://www.ovirt.org/wiki/Features/Design/cpu-pinning
+ cputune = self.doc.createElement('cputune')
+ cputuneParams = {'shares':1024}
+ if 'cputune' in self.conf:
+ cputuneParam = self.conf['cputune']
if 'cpuPinning' in self.conf:
- cputune = self.doc.createElement('cputune')
+ #CPU-pinning support
+ # see http://www.ovirt.org/wiki/Features/Design/cpu-pinning
cpuPinning = self.conf.get('cpuPinning')
try:
emulatorset = cpuPinning.pop('emulator')
@@ -754,7 +757,13 @@
vcpupin.setAttribute('vcpu', cpuPin)
vcpupin.setAttribute('cpuset', cpuPinning[cpuPin])
cputune.appendChild(vcpupin)
- self.dom.appendChild(cputune)
+
+ for item in cputuneParams.keys():
+ m = self.doc.createElement(item)
+ m.appendChild(self.doc.createTextNode(cputuneParams[item]))
+ cputune.appendChild(m)
+
+ self.dom.appendChild(cputune)
def _appendAgentDevice(self, path, name):
"""
@@ -1338,13 +1347,6 @@
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)
def _run(self):
self.log.info("VM wrapper has started")
--
To view, visit http://gerrit.ovirt.org/8445
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I76e9b9d291d4801965163774ba45d15b39a77471
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
9 years, 11 months
Change in vdsm[master]: virt: stats: move last fields the static group
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: virt: stats: move last fields the static group
......................................................................
virt: stats: move last fields the static group
WRITEME
Change-Id: I469759b86115d80bad62c3449fe9084d5f2e550b
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M vdsm/virt/vm.py
1 file changed, 3 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/57/26557/1
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index bbd47dd..84527b9 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -2413,9 +2413,6 @@
self._addBalloonInfoStats(stats)
self._addMigrationVmStats(stats)
- stats['hash'] = self._devXmlHash
- if self._watchdogEvent:
- stats["watchdogEvent"] = self._watchdogEvent
return stats
def _addExitedVmStats(self, stats):
@@ -2447,6 +2444,9 @@
stats['clientIp'] = self.conf.get('clientIp', '')
if 'pauseCode' in self.conf:
stats['pauseCode'] = self.conf['pauseCode']
+ stats['hash'] = self._devXmlHash
+ if self._watchdogEvent:
+ stats['watchdogEvent'] = self._watchdogEvent
def _addDynamicVmStats(self, stats):
decStats = {}
--
To view, visit http://gerrit.ovirt.org/26557
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I469759b86115d80bad62c3449fe9084d5f2e550b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: [WIP] VDSM <=> Engine data optimization
by Vinzenz Feenstra
Vinzenz Feenstra has uploaded a new change for review.
Change subject: [WIP] VDSM <=> Engine data optimization
......................................................................
[WIP] VDSM <=> Engine data optimization
Change-Id: Ifa0a7a86a351a8c2d891f22802a95d1fe1bc1df4
Signed-off-by: Vinzenz Feenstra <vfeenstr(a)redhat.com>
---
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/vm.py
M vdsm_api/vdsmapi-schema.json
4 files changed, 499 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/41/14541/1
diff --git a/vdsm/API.py b/vdsm/API.py
index ee72116..ebf331d 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -334,6 +334,66 @@
return errCode['noVM']
return v.migrateStatus()
+ def getRuntimeStats(self):
+ """
+ Retrieve runtime statistics for the specific VM
+ """
+ v = self._cif.vmContainer.get(self._UUID)
+ if not v:
+ return errCode['noVM']
+ return {
+ 'status': doneCode,
+ 'runtimeStats': {
+ self._UUID: v.getRuntimeStats().copy()}}
+
+ def getStatus(self):
+ """
+ Retrieve VM status information for the specific VM
+ """
+ v = self._cif.vmContainer.get(self._UUID)
+ if not v:
+ return errCode['noVM']
+ return {
+ 'status': doneCode,
+ 'vmStatus': {
+ self._UUID: v.getStatus().copy()}}
+
+ def getDeviceStats(self):
+ """
+ Retrieve device statistics for the specific VM
+ """
+ v = self._cif.vmcontainer.get(self._uuid)
+ if not v:
+ return errCode['noVM']
+ return {
+ 'status': doneCode,
+ 'deviceStats': {
+ self._UUID: v.getDeviceStats().copy()}}
+
+ def getConfInfo(self):
+ """
+ Retrieve configuration information for the specific VM
+ """
+ v = self._cif.vmcontainer.get(self._uuid)
+ if not v:
+ return errCode['noVM']
+ return {
+ 'status': doneCode,
+ 'info': {
+ self._UUID: v.getInfo().copy()}}
+
+ def getGuestDetails(self):
+ """
+ Retrieve guest information for the specific VM
+ """
+ v = self._cif.vmcontainer.get(self._uuid)
+ if not v:
+ return errCode['noVM']
+ return {
+ 'status': doneCode,
+ 'guestDetails': {
+ self._UUID: v.getGuestDetails().copy()}}
+
def getStats(self):
"""
Obtain statistics of the specified VM
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 9a4db12..912018c 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -314,6 +314,52 @@
vm = API.VM(vmId)
return vm.getStats()
+ def vmGetRuntimeStats(self, vmIds):
+ result = {}
+ for vmId in vmIds:
+ vm = API.VM(vmId)
+ result.update(vm.getRuntimeStats()['runtimeStats'])
+ return {
+ 'status': doneCode,
+ 'runtimeStats': result}
+
+ def vmGetStatus(self, vmIds):
+ result = {}
+ for vmId in vmIds:
+ vm = API.VM(vmId)
+ result.update(vm.getStatus()['vmStatus'])
+ return {
+ 'status': doneCode,
+ 'vmStatus': result}
+
+ def vmGetAllDeviceStats(self):
+ vms = self.getVMList()
+ result = {}
+ for vm in vms['vmList']:
+ v = API.VM(vm['vmId'])
+ result.update(v.getDeviceStats()['deviceStats'])
+ return {
+ 'status': doneCode,
+ 'deviceStats': result}
+
+ def vmGetConfInfo(self, vmIds):
+ result = {}
+ for vmId in vmIds:
+ vm = API.VM(vmId)
+ result.update(vm.getConfInfo()['vmConfInfo'])
+ return {
+ 'status': doneCode,
+ 'vmConfInfo': result}
+
+ def vmGetGuestDetails(self, vmIds):
+ result = {}
+ for vmId in vmIds:
+ vm = API.VM(vmId)
+ result.update(vm.getGuestDetails()['guestDetails'])
+ return {
+ 'status': doneCode,
+ 'guestDetails': result}
+
def getAllVmStats(self):
"""
Get statistics of all running VMs.
diff --git a/vdsm/vm.py b/vdsm/vm.py
index ddb09c8..6d57649 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -26,6 +26,7 @@
import tempfile
import pickle
from copy import deepcopy
+import json
from vdsm import utils
from vdsm.define import NORMAL, ERROR, doneCode, errCode
@@ -1115,6 +1116,65 @@
self.conf['status'] = self.lastStatus
return self.conf
+ def _hashObject(self, o):
+ return str(hash(json.dumps(o)))
+
+ def _getHashes(self, stats):
+ return {
+ 'info': self._hashObject(self._getInfo(stats)),
+ 'status': self._hashObject(self._getStatus(stats)),
+ 'guestDetals': self._hashObject(self._getGuestDetails(stats))}
+
+ def _extractKeys(self, dictObject, keys):
+ extracted = {}
+ for k in keys:
+ v = dictObject.get(k)
+ if v:
+ extracted[k] = v
+ return extracted
+
+ def getRuntimeStats(self):
+ allStats = self.getStats()
+ USED_KEYS = ('cpuSys', 'cpuUser', 'memUsage', 'elapsedTime', 'status',
+ 'statsAge')
+ stats = self._extractKeys(allStats, USED_KEYS)
+ stats['hashes'] = self._getHashes(allStats)
+ if 'hash' in allStats:
+ stats['hashes']['config'] = allStats['hash']
+ return stats
+
+ def _getStatus(self, stats):
+ USED_KEYS = ('timeOffset', 'monitorResponse', 'clientIp', 'lastLogin',
+ 'username', 'session', 'guestIPs')
+ return self._extractKeys(stats, USED_KEYS)
+
+ def getStatus(self):
+ return self._getStatus(self.getStats())
+
+ def _getDeviceStats(self, stats):
+ USED_KEYS = ('network', 'disks', 'disksUsage', 'balloonInfo',
+ 'memoryStats')
+ return self._extractKeys(stats, USED_KEYS)
+
+ def getDeviceStats(self):
+ return self._getDeviceStats(self.getStats())
+
+ def _getInfo(self, stats):
+ USED_KEYS = ('acpiEnable', 'vmType', 'guestName', 'guestOS',
+ 'kvmEnable', 'pauseCode', 'displayIp', 'displayPort',
+ 'displaySecurePort', 'pid')
+ return self._extractKeys(stats, USED_KEYS)
+
+ def getInfo(self):
+ return self._getInfo(self.getStats())
+
+ def _getGuestDetails(self, stats):
+ USED_KEYS = ('appList', 'netIfaces')
+ return self._extractKeys(stats, USED_KEYS)
+
+ def getGuestDetails(self):
+ return self._getGuestDetails(self.getStats())
+
def getStats(self):
# used by API.Vm.getStats
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 4ff8c7a..33be905 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -4850,6 +4850,339 @@
'data': {'vmID': 'UUID'},
'returns': 'VmDefinition'}
+##
+# @VmRuntimeStatsHashes:
+#
+# Hashes of several statistics and information around VMs
+#
+# @info: Hash for VmConfInfo data
+#
+# @config: Hash of the VM configuration XML
+#
+# @status: Hash of the VmStatusInfo data
+#
+# @guestDetails: Hash of the VmGuestDetails data
+#
+# Since: 4.10.3
+##
+{ 'type': 'VmRuntimeStatsHashes',
+ 'data': { 'info': 'str', 'config': 'str', 'status': 'str',
+ 'guestDetails': 'str'}}
+
+##
+# @VmRuntimeStats:
+#
+# Frequently changed and required data around VMs
+#
+# @cpuSys: Ratio of CPU time spent by qemu on other than guest time
+#
+# @cpuUser: Ratio of CPU time spent by the guest VM
+#
+# @memUsage: The percent of memory in use by the guest
+#
+# @elapsedTime: The number of seconds that the VM has been running
+#
+# @status: The current status of the given VM
+#
+# @statsAge: The age of these statistics in seconds
+#
+# @hashes: Hashes of several statistics and information around VMs
+#
+# Since: 4.10.3
+##
+{ 'type': 'VmRuntimeStats',
+ 'data': { 'cpuSys': 'float', 'cpuUser': 'float', 'memUsage': 'uint',
+ 'elapsedTime': 'uint', 'status': 'VmStatus', 'statsAge': 'float',
+ 'hashes': 'VmRuntimeStatsHashes'}}
+
+##
+# @VmRuntimeStatsResult:
+#
+# Union result of VmRuntimeStats or ExitedVmStats
+#
+# @exited: Indicates if the result is VmRuntimeStats or ExitedVmStats
+#
+# Since: 4.10.3
+##
+{'type': 'VmRuntimeStatsResult',
+ 'data': { 'exited': 'bool' },
+ 'union': ['VmRuntimeStats', 'ExitedVmStats']}
+
+##
+# @VmRuntimeStatsMap:
+#
+# A mapping of VM runtime statistics indexed by vm id (UUID).
+#
+# Since: 4.10.3
+##
+{'map': 'VmRuntimeStatsMap',
+ 'key': 'UUID', 'value': 'VmRuntimeStatsResult' }}
+
+
+##
+# @VM.getRuntimeStats:
+#
+# Get runtime information about a list of VMs
+#
+# @vmIDs: a list of UUIDs for VMs to query
+#
+# Returns:
+# VmRuntimeStatsMap
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'VM', 'name': 'getRuntimeStats'},
+ 'data': {'vmIDs': ['UUID']},
+ 'returns': 'VmRuntimeStatsMap'}
+
+##
+# @VmStatusInfo:
+#
+# Information to the status of a VM and less frequently changed information
+#
+# @timeOffset: The time difference from host to the VM in seconds
+#
+# @monitorResponse: Indicates if the qemu monitor is responsive
+#
+# @clientIp: The IP address of the client connected to the display
+#
+# @username: the username associated with the current session
+#
+# @session: The current state of user interaction with the VM
+#
+# @guestIPs: A space separated string of assigned IPv4 addresses
+#
+# @pauseCode: Indicates the reason a VM has been paused
+#
+# Since: 4.10.3
+##
+{ 'type': 'VmStatusInfo',
+ 'data': { 'timeOffset': 'uint', 'monitorResponse': 'int', 'clientIp': 'str',
+ 'username': 'str', 'session': 'GuestSessionState',
+ 'guestIPs': 'str', 'pauseCode': 'str'}}
+
+##
+# @VmStatusInfoResult:
+#
+# Union result of VmStatusInfo or ExitedVmStats
+#
+# @exited: Indicates if the result is VmStatusInfo or ExitedVmStats
+#
+# Since: 4.10.3
+##
+{'type': 'VmStatusInfoResult',
+ 'data': { 'exited': 'bool' },
+ 'union': ['VmStatusInfo', 'ExitedVmStats']}
+
+##
+# @VmStatusInfoMap:
+#
+# A mapping of VM status information indexed by vm id (UUID).
+#
+# Since: 4.10.3
+##
+{'map': 'VmStatusInfoMap',
+ 'key': 'UUID', 'value': 'VmStatusInfoResult'}
+
+##
+# @VM.getStatus:
+#
+# Get status information about a list of VMs
+#
+# @vmIDs: a list of UUIDs for VMs to query
+#
+# Returns:
+# VmStatusMap
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'VM', 'name': 'getStatus'},
+ 'data': {'vmIDs': ['UUID']},
+ 'returns': 'VmStatusInfoMap'}
+
+##
+# @VmConfInfo:
+#
+# VM configuration information
+#
+# @acpiEnable: Indicates if ACPI is enabled inside the VM
+#
+# @displayPort: The port in use for unencrypted display data
+#
+# @displaySecurePort: The port in use for encrypted display data
+#
+# @displayType: The type of display in use
+#
+# @displayIp: The IP address to use for accessing the VM display
+#
+# @pid: The process ID of the underlying qemu process
+#
+# @vmType: The type of VM
+#
+# @kvmEnable: Indicates if KVM hardware acceleration is enabled
+#
+# @cdrom: #optional The path to an ISO image used in the VM's CD-ROM device
+#
+# @boot: #optional An alias for the type of device used to boot the VM
+#
+# Since: 4.10.3
+##
+{ 'type': 'VmConfInfo',
+ 'data': { 'acpiEnable': 'bool', 'vmType': 'VmType',
+ 'kvmEnable': 'bool', 'displayIp': 'str', 'displayPort': 'uint',
+ 'displaySecurePort': 'uint', 'displayType': 'VmDisplayType',
+ 'pid': 'uint', '*boot': 'VmBootMode', '*cdrom': 'str'}}
+
+##
+# @VmConfInfoResult:
+#
+# Union result of VmConfInfo or ExitedVmStats
+#
+# @exited: Indicates if the result is VmConfInfo or ExitedVmStats
+#
+# Since: 4.10.3
+##
+{'type': 'VmConfInfoResult',
+ 'data': { 'exited': 'bool' },
+ 'union': ['VmConfInfo', 'ExitedVmStats']}
+
+##
+# @VmConfInfoMap:
+#
+# A mapping of VM config information indexed by vm id (UUID).
+#
+# Since: 4.10.3
+##
+{'map': 'VmConfInfoMap',
+ 'key': 'UUID', 'value': 'VmConfInfoResult' }}
+
+##
+# @VM.getConfInfo:
+#
+# Get configuration information about a list of VMs
+#
+# @vmIDs: a list of UUIDs for VMs to query
+#
+# Returns:
+# VmConfInfoMap
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'VM', 'name': 'getConfInfo'},
+ 'data': {'vmIDs': ['UUID']},
+ 'returns': 'VmConfInfoMap'}
+
+##
+# @VmDeviceStats:
+#
+# VM device statistics containing information for getting statistics and SLA
+# information.
+#
+# @memoryStats: Memory statistics as reported by the guest agent
+#
+# @balloonInfo: Guest memory balloon information
+#
+# @disksUsage: Info about mounted filesystems as reported by the agent
+#
+# @network: Network bandwidth/utilization statistics
+#
+# @disks: Disk bandwidth/utilization statistics
+#
+# Since: 4.10.3
+##
+{ 'type': 'VmDeviceStats',
+ 'data': { 'network': 'NetworkInterfaceStatsMap', 'disks': 'VmDiskStatsMap',
+ 'disksUsage': ['GuestMountInfo'], 'balloonInfo': 'BalloonInfo',
+ 'memoryStats': 'GuestMemoryStats' }}
+
+##
+# @VmDeviceStatsResult:
+#
+# Union result of VmDeviceStats or ExitedVmStats
+#
+# @exited: Indicates if the result is VmDeviceStats or ExitedVmStats
+#
+# Since: 4.10.3
+##
+{'type': 'VmDeviceStatsResult',
+ 'data': { 'exited': 'bool' },
+ 'union': ['VmDeviceStats', 'ExitedVmStats']}
+
+##
+# @VmDeviceStatsMap:
+#
+# A mapping of VM device statistics indexed by vm id (UUID).
+#
+# Since: 4.10.3
+##
+{'map': 'VmDeviceStatsMap',
+ 'key': 'UUID', 'value': 'VmDeviceStatsResult' }}
+
+##
+# @VM.getAllDeviceStats:
+#
+# Get device statistics from all VMs
+#
+# Returns:
+# VmDeviceStatsMap
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'VM', 'name': 'getAllDeviceStats'},
+ 'returns': 'VmDeviceStatsMap'}
+
+##
+# @VmGuestDetails:
+#
+# Non-frequent changed details from guest OSes
+#
+# @appsList: A list of installed applications with their versions
+#
+# @netIfaces: Network device address info as reported by the agent
+#
+# Since: 4.10.3
+##
+{ 'type': 'VmGuestDetails',
+ 'data': { 'appsList': ['str'], 'netIfaces': ['GuestNetworkDeviceInfo'] }}
+
+##
+# @VmGuestDetailsResult:
+#
+# Union result of VmDeviceStats or ExitedVmStats
+#
+# @exited: Indicates if the result is VmGuestDetails or ExitedVmStats
+#
+# Since: 4.10.3
+##
+{'type': 'VmGuestDetailsResult',
+ 'data': { 'exited': 'bool' },
+ 'union': ['VmGuestDetails', 'ExitedVmStats']}
+
+##
+# @VmGuestDetailsMap:
+#
+# A mapping of detailed information of guests indexed by vm id (UUID).
+#
+# Since: 4.10.3
+##
+{'map': 'VmGuestDetailsMap',
+ 'key': 'UUID', 'value': 'VmGuestDetailsResult' }}
+
+##
+# @VM.getGuestDetails:
+#
+# Get details from the guest OS from a list of VMs
+#
+# @vmIDs: a list of UUIDs for VMs to query
+#
+# Returns:
+# VmGuestDetailsMap
+#
+# Since: 4.10.3
+##
+{'command': {'class': 'VM', 'name': 'getGuestDetails'},
+ 'data': {'vmIDs': ['UUID']},
+ 'returns': 'VmGuestDetailsMap'}
##
# @VM.getMigrationStatus:
--
To view, visit http://gerrit.ovirt.org/14541
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifa0a7a86a351a8c2d891f22802a95d1fe1bc1df4
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <vfeenstr(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: Adding "updateVmPolicy" api
by kobi@redhat.com
Kobi Ianko has uploaded a new change for review.
Change subject: Adding "updateVmPolicy" api
......................................................................
Adding "updateVmPolicy" api
Adding an API method "updateVmPolicy".
The method will be called from the engine
when a VM SLA parameter will change, for now
it will support the change of vcpuLimit.
Change-Id: I9750667c4d20d7589a1797e65d5683692ec02afe
Signed-off-by: Kobi Ianko <kianku(a)redhat.com>
---
M client/vdsClient.py
M lib/vdsm/define.py
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/virt/vm.py
M vdsm_api/Bridge.py
M vdsm_api/vdsmapi-schema.json
7 files changed, 71 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/72/27272/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index 9764ea5..564ba40 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -258,6 +258,10 @@
def setNumberOfCpus(self, args):
return self.ExecAndExit(self.s.setNumberOfCpus(args[0], args[1]))
+ def updateVmPolicy(self, args):
+ params = {'vmId': args[0], 'vcpuLimit':args[1]}
+ return self.ExecAndExit(self.s.updateVmPolicy(params))
+
def do_changeCD(self, args):
vmId = args[0]
file = self._parseDriveSpec(args[1])
@@ -2556,6 +2560,11 @@
'<vmId> <numberOfCpus>',
'set the number of cpus for a running VM'
)),
+ 'updateVmPolicy': (
+ serv.updateVmPolicy, (
+ '<vmId> <vcpuLimit>',
+ 'set SLA parameter for a VM'
+ )),
}
if _glusterEnabled:
commands.update(ge.getGlusterCmdDict(serv))
diff --git a/lib/vdsm/define.py b/lib/vdsm/define.py
index 7e6cadb..025d952 100644
--- a/lib/vdsm/define.py
+++ b/lib/vdsm/define.py
@@ -138,6 +138,9 @@
'haErr': {'status': {
'code': 61,
'message': 'Failed to set Hosted Engine HA policy'}},
+ 'updateVmPolicyErr': {'status': {
+ 'code': 62,
+ 'message': 'Failed to update VM SLA policy'}},
'recovery': {'status': {
'code': 99,
'message': 'Recovering from crash or Initializing'}},
diff --git a/vdsm/API.py b/vdsm/API.py
index 94b39b6..304cbc0 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -482,6 +482,22 @@
return curVm.setNumberOfCpus(int(numberOfCpus))
+ def updateVmPolicy(self, params):
+
+ if params['vmId'] is None or params['vcpuLimit'] is None:
+ self.log.error('Missing one of required parameters: \
+ vmId: (%s), numberOfCpus: (%s)', params['vmId'], params['vcpuLimit'])
+ return {'status': {'code': errCode['MissParam']['status']['code'],
+ 'message': 'Missing one of required '
+ 'parameters: vmId, vcpuLimit'}}
+ try:
+ curVm = self._cif.vmContainer[self._UUID]
+ except KeyError:
+ self.log.warning("vm %s doesn't exist", self._UUID)
+ return errCode['noVM']
+
+ return curVm.updateVmPolicy(params)
+
def migrate(self, params):
"""
Migrate a VM to a remote host.
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 76251f5..6bbc333 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -359,6 +359,10 @@
vm = API.VM(vmId)
return vm.setNumberOfCpus(vmId, numberOfCpus)
+ def vmUpdateVmPolicy(self, params):
+ vm = API.VM(params['vmId'])
+ return vm.updateVmPolicy(params)
+
def vmSnapshot(self, vmId, snapDrives, snapMemVolHandle=''):
"""
Take snapshot of VM
@@ -939,7 +943,8 @@
(self.vmHotplugNic, 'hotplugNic'),
(self.vmHotunplugNic, 'hotunplugNic'),
(self.vmUpdateDevice, 'vmUpdateDevice'),
- (self.vmSetNumberOfCpus, 'setNumberOfCpus'))
+ (self.vmSetNumberOfCpus, 'setNumberOfCpus')
+ (self.vmUpdateVmPolicy, 'updateVmPolicy'))
def getIrsMethods(self):
return ((self.domainActivate, 'activateStorageDomain'),
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 670e8b8..87360c8 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -3174,6 +3174,25 @@
hooks.after_set_num_of_cpus()
return {'status': doneCode, 'vmList': self.status()}
+ def updateVmPolicy(self, params):
+
+ if self.isMigrating():
+ return errCode['migInProgress']
+
+ self.log.debug("Setting VM policy to [vcpuLimit: %s]", params['vcpuLimit'])
+# hooks.before_set_num_of_cpus()
+ try:
+ domain = self._connection.lookupByUUIDString(self.id)
+ domain.setMetadata(2, params['vcpuLimit'], 'http://ovirt.org/param/vcpu_limit',0)
+ except libvirt.libvirtError as e:
+ self.log.error("updateVmPolicy failed", exc_info=True)
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return errCode['noVM']
+ return {'status': {'code': errCode['updateVmPolicyErr']
+ ['status']['code'], 'message': e.message}}
+
+ return {'status': doneCode }
+
def _createTransientDisk(self, diskParams):
if diskParams.get('shared', None) != DRIVE_SHARED_TYPE.TRANSIENT:
return
diff --git a/vdsm_api/Bridge.py b/vdsm_api/Bridge.py
index 566587f..42506f9 100644
--- a/vdsm_api/Bridge.py
+++ b/vdsm_api/Bridge.py
@@ -364,6 +364,7 @@
'VM_mergeStatus': {'ret': 'mergeStatus'},
'VM_migrationCreate': {'ret': VM_migrationCreate_Ret},
'VM_setNumberOfCpus': {'ret': 'vmList'},
+ 'VM_updateVmPolicy': {'ret'},
'Volume_copy': {'ret': 'uuid'},
'Volume_create': {'ret': 'uuid'},
'Volume_delete': {'ret': 'uuid'},
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 31bd869..81be9cc 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -7088,3 +7088,20 @@
{'command': {'class': 'VM', 'name': 'setNumberOfCpus'},
'data': {'vmID': 'UUID', 'numberOfCpus': 'int'},
'returns': 'VmDefinition'}
+
+ ##
+# @VM.updateVmPolicy:
+#
+# Set VM SLA parameters
+#
+# @vmID: The UUID of the VM
+#
+# @vcpuLimit: vcpu limit to set
+#
+# Returns:
+# The VM definition, as updated
+#
+# Since: 4.15.0
+##
+{'command': {'class': 'VM', 'name': 'updateVmPolicy'},
+ 'data': {'vmID': 'UUID', 'vcpuLimit': 'int'}}
--
To view, visit http://gerrit.ovirt.org/27272
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9750667c4d20d7589a1797e65d5683692ec02afe
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Kobi Ianko <kobi(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: Adding utility methods and conf for CPU limit MOM integration
by kobi@redhat.com
Kobi Ianko has uploaded a new change for review.
Change subject: Adding utility methods and conf for CPU limit MOM integration
......................................................................
Adding utility methods and conf for CPU limit MOM integration
Adding a MOM policy to monitor CPU tuning parameter.
Adding utility methods to vm.py to integrate with MOM's collectors and controllers
Change-Id: Ic502d9a4a976cd76bb6042bbb51f6cd281199631
Signed-off-by: Kobi Ianko <kianku(a)redhat.com>
---
M vdsm/mom.conf.in
M vdsm/mom.d/00-defines.policy
A vdsm/mom.d/04-cputune.policy
M vdsm/virt/vm.py
4 files changed, 139 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/58/27258/1
diff --git a/vdsm/mom.conf.in b/vdsm/mom.conf.in
index ba11038..fd5f997 100644
--- a/vdsm/mom.conf.in
+++ b/vdsm/mom.conf.in
@@ -67,8 +67,8 @@
[host]
# A comma-separated list of Collector plugins to use for Host data collection.
-collectors: HostMemory, HostKSM
+collectors: HostMemory, HostKSM, HostCpu
[guest]
# A comma-separated list of Collector plugins to use for Guest data collection.
-collectors: GuestQemuProc, GuestMemory, GuestBalloon
+collectors: GuestQemuProc, GuestMemory, GuestBalloon, GuestCpuTune
diff --git a/vdsm/mom.d/00-defines.policy b/vdsm/mom.d/00-defines.policy
index 93b70ee..2def4c9 100644
--- a/vdsm/mom.d/00-defines.policy
+++ b/vdsm/mom.d/00-defines.policy
@@ -6,4 +6,7 @@
# Define variables for configurable options here
(defvar ksmEnabled 1)
(defvar balloonEnabled 0)
+(defvar cpuTuneEnabled 0)
+(defvar vcpuQuota -1)
+(defvar vcpuPeriod 1000)
diff --git a/vdsm/mom.d/04-cputune.policy b/vdsm/mom.d/04-cputune.policy
new file mode 100644
index 0000000..3e53cd5
--- /dev/null
+++ b/vdsm/mom.d/04-cputune.policy
@@ -0,0 +1,48 @@
+### Auto-CpuTune ###############################################################
+
+(defvar anchor 100000)
+(defvar defaultQuota -1)
+(defvar defaultPeriod 1000)
+
+(defvar calcPeriod (/ anchor Host.cpu_count))
+
+### Helper functions
+(def check_and_set_quota (guest)
+{
+
+ (defvar calcQuota (/ (* anchor (/ guest.user_vcpu_limit 100))) guest.vcpu_count)
+
+ (if (!= guest.vcpu_quota calcQuota)
+ (guest.Control "vcpu_quota" calcQuota) 0)
+})
+
+(def check_and_set_period (guest)
+{
+ (if (!= guest.vcpu_period calcPeriod)
+ (guest.Control "vcpu_period" calcPeriod) 0)
+})
+
+(def reset_quota_and_period (guest)
+{
+ (guest.Control "vcpu_quota" defaultQuota)
+ (guest.Control "vcpu_period" defaultPeriod)
+})
+
+
+### Main script
+# Methodology: The goal is to set the quota and period of the vcpuTune
+# to the values the user selected, the user setting will update once
+# a policy sync is made.
+
+# If the CpuTune is disabled, reset setting
+# else set the quota and period
+
+
+
+(if (== True cpuTuneEnabled) {
+ (with Guests guest (check_and_set_quota guest))
+ (with Guests guest (check_and_set_period guest))
+} {
+ (with Guests guest (reset_quota_and_period guest))
+})
+
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 6711bc6..41cea1e 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -2500,6 +2500,9 @@
int(self.conf['memSize']) * 100)
stats['memUsage'] = utils.convertToStr(int(memUsage))
stats['balloonInfo'] = self._getBalloonInfo()
+ stats['userCpuTuneInfo'] = self._getUserCpuTuneInfo()
+ stats['cpuTuneInfo'] = self._getCpuTuneInfo()
+ stats['cpu_count'] = self._getCpuCount()
if self.isMigrating():
stats['migrationProgress'] = self.migrateStatus()['progress']
return stats
@@ -4327,6 +4330,40 @@
'balloon_target': str(target_mem)}
return {}
+ def _getUserCpuTuneInfo(self):
+ ret = {}
+ domain = self._connection.lookupByUUIDString(self.id)
+
+ metadataCpuLimit = domain.getMetadata(2,'http://ovirt.org/param/vcpu_limit',0)
+
+ if metadataCpuLimit:
+ ret['user_vcpu_limit'] = metadataCpuLimit
+ else:
+ ret['user_vcpu_quota'] = 100
+
+ return ret
+
+ def _getCpuTuneInfo(self):
+ domain = self._connection.lookupByUUIDString(self.id)
+
+ ret = domain.getSchedulerParameters({ 'vcpu_quota', 'vcpu_period'})
+
+ if ret['vcpu_quota'] == None:
+ ret['vcpu_quota'] = -1
+
+ if ret['vcpu_period'] == None:
+ ret['vcpu_period'] = 1000
+
+ return ret
+
+ def _getCpuCount(self):
+
+ domain = self._connection.lookupByUUIDString(self.id)
+ if domain.getMaxVcpus() != -1 :
+ return domain.getMaxVcpus()
+ else:
+ return 0
+
def setBalloonTarget(self, target):
def reportError(key='balloonErr', msg=None):
@@ -4358,6 +4395,55 @@
self.saveState()
return {'status': doneCode}
+
+ def setCpuTuneQuota(self, quota):
+
+ def reportError(key='cpuTuneErr', msg=None):
+ self.log.error("Set new vcpu quota failed", exc_info=True)
+ if msg is None:
+ error = errCode[key]
+ else:
+ error = {'status': {'code': errCode[key]
+ ['status']['code'], 'message': msg}}
+ return error
+
+ if self._dom is None:
+ return reportError()
+ try:
+ quota = int(quota)
+ self._dom.setSchedulerParameters({ 'vcpu_quota': quota})
+ return {'status': doneCode}
+ except ValueError:
+ return reportError(msg='an integer is required for quota')
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return reportError(key='noVM')
+ return reportError(msg=e.message)
+
+ def setCpuTunePeriod(self, period):
+
+ def reportError(key='cpuTuneErr', msg=None):
+ self.log.error("Set new vcpu period failed", exc_info=True)
+ if msg is None:
+ error = errCode[key]
+ else:
+ error = {'status': {'code': errCode[key]
+ ['status']['code'], 'message': msg}}
+ return error
+
+ if self._dom is None:
+ return reportError()
+ try:
+ period = int(period)
+ self._dom.setSchedulerParameters({ 'vcpu_period': period})
+ return {'status': doneCode}
+ except ValueError:
+ return reportError(msg='an integer is required for period')
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ return reportError(key='noVM')
+ return reportError(msg=e.message)
+
def _getUnderlyingDeviceAddress(self, devXml):
"""
Obtain device's address from libvirt
--
To view, visit http://gerrit.ovirt.org/27258
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic502d9a4a976cd76bb6042bbb51f6cd281199631
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Kobi Ianko <kobi(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: gluster: Get size information of a gluster volume.
by dnarayan@redhat.com
Darshan N has uploaded a new change for review.
Change subject: gluster: Get size information of a gluster volume.
......................................................................
gluster: Get size information of a gluster volume.
New vdsm gluster verb to get free, used and total size of
gluster volume. This verb uses gluster-libgfapi to get the
statistics related to volume.
verb: glusterVolumeStatsInfoGet
Output format:
{"sizeTotal": LONG as STR, "sizeFree": LONG as STR, "sizeUsed": LONG as STR}
Exception(s):
code: 4570
Name: GlusterVolumeStatsInfoGetFailedException
Message: Failed to get Gluster volume <VOL NAME> Stats
code: 4571
Name: GlusterVolumeIsNotOnlineException
Message: Failed to get Gluster volume stats
Change-Id: Ib628b10c3b9743bb9fef5cbf41195e69ff851efd
Signed-off-by: Darshan n <dnarayan(a)redhat.com>
---
M client/vdsClientGluster.py
M configure.ac
M vdsm.spec.in
M vdsm/Makefile.am
M vdsm/gluster/Makefile.am
M vdsm/gluster/__init__.py
M vdsm/gluster/api.py
M vdsm/gluster/exception.py
A vdsm/gluster/statvfs.py
M vdsm/gluster/vdsmapi-gluster-schema.json
A vdsm/gluster_glfs/Makefile.am
A vdsm/gluster_glfs/__init__.py
A vdsm/gluster_glfs/glfs_vol.h
A vdsm/gluster_glfs/setup.py
A vdsm/gluster_glfs/volCap.c
15 files changed, 313 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/43/26343/1
diff --git a/client/vdsClientGluster.py b/client/vdsClientGluster.py
index 9fa58b2..421c853 100644
--- a/client/vdsClientGluster.py
+++ b/client/vdsClientGluster.py
@@ -422,6 +422,14 @@
pp.pprint(status)
return status['status']['code'], status['status']['message']
+ def do_glusterVolumeStatsInfoGet(self, args):
+ params = self._eqSplit(args)
+ volumeName = params.get('volumeName', '')
+
+ status = self.s.glusterVolumeStatsInfoGet(volumeName)
+ pp.pprint(status)
+ return status['status']['code'], status['status']['message']
+
def getGlusterCmdDict(serv):
return \
@@ -718,4 +726,9 @@
('[taskIds=<task_id1,task_id2,..>]',
'list all or given gluster tasks'
)),
+ 'glusterVolumeStatsInfoGet': (
+ serv.do_glusterVolumeStatsInfoGet,
+ ('volumeName=<volume name>',
+ 'Returns total, free and used space(bytes) of gluster volume'
+ )),
}
diff --git a/configure.ac b/configure.ac
index 71f91bc..d260e4b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,6 +270,7 @@
vdsm-tool/Makefile
vdsm/Makefile
vdsm/gluster/Makefile
+ vdsm/gluster_glfs/Makefile
vdsm/netconf/Makefile
vdsm/sos/Makefile
vdsm/storage/Makefile
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 6c92b15..77e563e 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1,4 +1,3 @@
-# Packages names
%global vdsm_name vdsm
%global vdsm_bootstrap vdsm-bootstrap
%global vdsm_reg vdsm-reg
@@ -61,6 +60,7 @@
BuildRequires: python-nose
BuildRequires: python-netaddr
BuildRequires: rpm-build
+BuildRequires: glusterfs-devel
# BuildRequires needed by the tests during the build
BuildRequires: dosfstools
@@ -587,7 +587,6 @@
%if 0%{?with_gluster}
%package gluster
Summary: Gluster Plugin for VDSM
-BuildArch: noarch
Requires: %{name} = %{version}-%{release}
Requires: glusterfs-server
@@ -629,6 +628,7 @@
# Install the respawn utility
install -Dm 0755 init/sysvinit/respawn \
%{buildroot}%{_datadir}/%{vdsm_name}/respawn
+
# Install the lvm rules
install -Dm 0644 vdsm/storage/vdsm-lvm.rules \
@@ -1431,12 +1431,22 @@
%dir %{_datadir}/%{vdsm_name}/gluster
%doc COPYING
%{_datadir}/%{vdsm_name}/gluster/api.py*
+%{_datadir}/%{vdsm_name}/gluster/statvfs.py*
%{_datadir}/%{vdsm_name}/gluster/vdsmapi-gluster-schema.json
%{_datadir}/%{vdsm_name}/gluster/hooks.py*
%{_datadir}/%{vdsm_name}/gluster/services.py*
%{_datadir}/%{vdsm_name}/gluster/tasks.py*
%endif
+%if 0%{?with_gluster}
+%defattr(-, root, root, -)
+%dir %{_datadir}/%{vdsm_name}/gluster_glfs
+%doc COPYING
+%{_datadir}/%{vdsm_name}/gluster_glfs/__init__.py*
+%{_datadir}/%{vdsm_name}/gluster_glfs/capacity.so*
+%endif
+
+
%changelog
* Sun Oct 13 2013 Yaniv Bronhaim <ybronhei(a)redhat.com> - 4.13.0
- Removing vdsm-python-cpopen from the spec
diff --git a/vdsm/Makefile.am b/vdsm/Makefile.am
index 8ab0072..4e34936 100644
--- a/vdsm/Makefile.am
+++ b/vdsm/Makefile.am
@@ -18,7 +18,7 @@
# Refer to the README and COPYING files for full details of the license
#
-SUBDIRS = netconf sos storage gluster
+SUBDIRS = netconf sos storage gluster gluster_glfs
include $(top_srcdir)/build-aux/Makefile.subs
diff --git a/vdsm/gluster/Makefile.am b/vdsm/gluster/Makefile.am
index b397e95..f30d67f 100644
--- a/vdsm/gluster/Makefile.am
+++ b/vdsm/gluster/Makefile.am
@@ -32,6 +32,7 @@
cli.py \
exception.py \
hooks.py \
+ statvfs.py \
services.py \
tasks.py \
$(NULL)
diff --git a/vdsm/gluster/__init__.py b/vdsm/gluster/__init__.py
index 0aefb8d..f86a5dc 100644
--- a/vdsm/gluster/__init__.py
+++ b/vdsm/gluster/__init__.py
@@ -22,7 +22,7 @@
import tempfile
from functools import wraps
-MODULE_LIST = ('cli', 'hooks', 'services', 'tasks')
+MODULE_LIST = ('cli', 'hooks', 'services', 'tasks', 'statvfs')
def makePublic(func):
diff --git a/vdsm/gluster/api.py b/vdsm/gluster/api.py
index 761ee78..506cd10 100644
--- a/vdsm/gluster/api.py
+++ b/vdsm/gluster/api.py
@@ -306,6 +306,12 @@
status = self.svdsmProxy.glusterTasksList(taskIds)
return {'tasks': status}
+ @exportAsVerb
+ def volumeStatsInfoGet(self, volumeName, volumeServer='localhost',
+ options=None):
+ return self.svdsmProxy.glusterVolumeStatsInfoGet(volumeName,
+ volumeServer)
+
def getGlusterMethods(gluster):
l = []
diff --git a/vdsm/gluster/exception.py b/vdsm/gluster/exception.py
index 93a2225..1295ce4 100644
--- a/vdsm/gluster/exception.py
+++ b/vdsm/gluster/exception.py
@@ -486,3 +486,13 @@
prefix = "%s: " % (action)
self.message = prefix + "Service action is not supported"
self.err = [self.message]
+
+
+class GlusterVolumeStatsInfoGetFailedException(GlusterException):
+ code = 4570
+ message = "Failed to get Gluster volume Stats"
+
+
+class GlusterVolumeIsNotOnlineException(GlusterVolumeException):
+ code = 4571
+ message = "Failed to get Gluster volume stats"
diff --git a/vdsm/gluster/statvfs.py b/vdsm/gluster/statvfs.py
new file mode 100644
index 0000000..af8ea92
--- /dev/null
+++ b/vdsm/gluster/statvfs.py
@@ -0,0 +1,60 @@
+#
+# Copyright 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+import logging
+from gluster_glfs.capacity import statvfs
+import exception as ge
+from . import makePublic
+from . import cli
+
+log = logging.getLogger("Gluster")
+
+
+@makePublic
+def volumeStatsInfoGet(volumeName, volumeServer="localhost"):
+ volume_data = cli.volumeInfo(volumeName=volumeName,
+ remoteServer=volumeServer)
+ if volumeName not in volume_data:
+ msg = "Volume \"%s\" does not exists" % volumeName
+ raise ge.GlusterVolumeNameErrorException(err=[msg])
+
+ if volume_data[volumeName]['volumeStatus'] == cli.VolumeStatus.OFFLINE:
+ msg = "Volume \"%s\" is not Online" % volumeName
+ raise ge.GlusterVolumeIsNotOnlineException(err=[msg])
+
+ try:
+ statvfsData = statvfs(volumeName, volumeServer)
+ except:
+ errMsg = "Failed to retrive statistics"
+ " of glusterfs volume %s" % volumeName
+ raise ge.GlusterVolumeSizeInfoGetFailedException(err=[errMsg])
+
+ # f_blocks = Total number of blocks
+ # f_bfree = Total number of blocks free
+ # f_bavail = Total number of blocks available for non root user
+ # total blocks available = f_blocks - (f_bfree - f_bavail)
+ total = ((statvfsData['f_blocks'] -
+ (statvfsData['f_bfree'] - statvfsData['f_bavail'])) *
+ statvfsData['f_bsize'])
+ free = statvfsData['f_bavail'] * statvfsData['f_bsize']
+ used = total - free
+
+ return {'sizeTotal': str(total),
+ 'sizeFree': str(free),
+ 'sizeUsed': str(used)}
diff --git a/vdsm/gluster/vdsmapi-gluster-schema.json b/vdsm/gluster/vdsmapi-gluster-schema.json
index 4e80679..7c30c9e 100644
--- a/vdsm/gluster/vdsmapi-gluster-schema.json
+++ b/vdsm/gluster/vdsmapi-gluster-schema.json
@@ -1205,3 +1205,37 @@
##
{'command': {'class': 'GlusterHost', 'name': 'list'},
'returns': ['HostList']}
+
+##
+# @GlusterVolumeStatsInfo:
+#
+# Gluster Volumes disk usage statistics
+#
+# @sizeTotal: Total space available in bytes
+#
+# @sizeFree: Free space available in bytes
+#
+# @sizeUsed: Used space in bytes
+#
+# Since: 4.14.0
+##
+{'type': 'GlusterVolumeStatsInfo',
+ 'data': {'sizeTotal': 'str', 'sizeFree': 'str', 'sizeUsed': 'str'}}
+
+##
+# @GlusterVolume.statsInfoGet:
+#
+# Get the list of Gluster volumes
+#
+# @volumeName: Gluster volume name
+#
+# @volumeServer: Gluster volume server default is localhost
+#
+# Returns:
+# Stats info of GlusterFS volume
+#
+# Since: 4.14.0
+##
+{'command': {'class': 'GlusterVolume', 'name': 'statsInfoGet'},
+ 'data': {'volumeName': 'str', 'volumeServer': 'str'},
+ 'returns': 'GlusterVolumeStatsInfo'}
diff --git a/vdsm/gluster_glfs/Makefile.am b/vdsm/gluster_glfs/Makefile.am
new file mode 100644
index 0000000..f10158a
--- /dev/null
+++ b/vdsm/gluster_glfs/Makefile.am
@@ -0,0 +1,19 @@
+statisticsdir = $(vdsmdir)/gluster_glfs
+dist_statistics_PYTHON = \
+ __init__.py \
+ capacity.so \
+ $(NULL)
+
+capacity.so: volCap.c setup.py
+ (cd $(srcdir);$(PYTHON) setup.py build \
+ --build-temp $(abs_builddir) --build-lib $(abs_builddir))
+
+all-local: capacity.so
+
+EXTRA_DIST = \
+ __init__.py \
+ volCap.c \
+ setup.py
+CLEANFILES = \
+ volcap.o \
+ capacity.so
diff --git a/vdsm/gluster_glfs/__init__.py b/vdsm/gluster_glfs/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vdsm/gluster_glfs/__init__.py
diff --git a/vdsm/gluster_glfs/glfs_vol.h b/vdsm/gluster_glfs/glfs_vol.h
new file mode 100644
index 0000000..80c8434
--- /dev/null
+++ b/vdsm/gluster_glfs/glfs_vol.h
@@ -0,0 +1,41 @@
+#include <syslog.h>
+
+#define GLFS_INIT_FAILURE -3
+#define GLFS_FINI_FAILURE -5
+#define DEFAULT_TRANSPORT "tcp"
+#define DEFAULT_SERVER "127.0.0.1"
+#define DEFAULT_SERVER_PORT 24007
+
+int get_volume (const char *volume_name, const char *server_name, glfs_t *fs)
+{
+ int ret = 0;
+ int rv = 0;
+
+ if (server_name)
+ {
+ ret = glfs_set_volfile_server(fs, DEFAULT_TRANSPORT, server_name, DEFAULT_SERVER_PORT);
+ }
+ else
+ {
+ ret = glfs_set_volfile_server(fs, DEFAULT_TRANSPORT, DEFAULT_SERVER, DEFAULT_SERVER_PORT);
+ }
+
+ ret = glfs_set_logging (fs, "/tmp/libg.txt", 2);
+
+ ret = glfs_init (fs);
+ if (ret != 0)
+ {
+ syslog (LOG_ERR, "glfs_init() failed with code %d",ret);
+ rv = GLFS_INIT_FAILURE;
+ ret = glfs_fini (fs);
+ if (ret != 0)
+ {
+ syslog (LOG_ERR, "glfs_fini() failed with code %d\n", ret);
+ }
+
+ return rv;
+ }
+ sleep(3);
+ return 0;
+}
+
diff --git a/vdsm/gluster_glfs/setup.py b/vdsm/gluster_glfs/setup.py
new file mode 100644
index 0000000..e934817
--- /dev/null
+++ b/vdsm/gluster_glfs/setup.py
@@ -0,0 +1,11 @@
+from distutils.core import setup, Extension
+
+module1 = Extension('capacity', sources=['volCap.c'],
+ libraries=['gfapi'])
+
+setup(name='capacity',
+ version='1.0',
+ description='gets volume capacity',
+ py_modules=['__init__'],
+ url='redhat.com',
+ ext_modules=[module1])
diff --git a/vdsm/gluster_glfs/volCap.c b/vdsm/gluster_glfs/volCap.c
new file mode 100644
index 0000000..bd3c646
--- /dev/null
+++ b/vdsm/gluster_glfs/volCap.c
@@ -0,0 +1,103 @@
+#include <Python.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#include "/usr/include/glusterfs/api/glfs.h"
+#include "/usr/include/glusterfs/api/glfs-handles.h"
+#include "glfs_vol.h"
+
+#define USAGE_ERROR -1
+#define GLFS_NEW_FAILURE -2
+#define GLFS_STATVFS_FAILURE -4
+
+static PyObject *StatvfsError;
+
+int get_volume_statvfs (const char *volume_name, const char *server_name, struct statvfs *buf)
+{
+ glfs_t *fs = NULL;
+ int ret = 0;
+ struct statvfs statvfsinfo = {0, };
+ int rv = 0;
+
+ if (!(volume_name && buf))
+ {
+ return USAGE_ERROR;
+ }
+
+ fs = glfs_new (volume_name);
+ if (!fs)
+ {
+ syslog (LOG_ERR, "glfs_new: returned NULL");
+ return GLFS_NEW_FAILURE;
+ }
+ ret = get_volume(volume_name, server_name, fs);
+ if(ret!=0)
+ {
+ return ret;
+ }
+ ret = glfs_statvfs (fs, "/", &statvfsinfo);
+ if (ret == 0)
+ {
+ *buf = statvfsinfo;
+ }
+ else
+ {
+ syslog (LOG_ERR, "glfs_statvfs() failed with [%d:%s] for \"/\"\n", ret, strerror (errno));
+ rv = GLFS_STATVFS_FAILURE;
+ }
+ ret = glfs_fini (fs);
+ if (ret != 0)
+ {
+ syslog (LOG_ERR, "glfs_fini() failed with code %d\n", ret);
+ }
+ return rv;
+}
+
+static PyObject *glfspy_statvfs (PyObject *self, PyObject *args)
+{
+ char *volume_name = NULL;
+ char *server_name = NULL;
+ int port = 0;
+ char *transport = NULL;
+ struct statvfs buf = {0, };
+ int rv = 0;
+
+ StatvfsError = PyErr_NewException("statvfs.error", NULL, NULL);
+ setlogmask (LOG_UPTO (LOG_DEBUG));
+ openlog ("statvfs", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
+ syslog (LOG_INFO, "Invoking glfspy_statvfs to get the volume utlization");
+
+ if (!PyArg_ParseTuple (args, "s|ziz", &volume_name, &server_name, &port, &transport))
+ {
+ PyErr_SetString(StatvfsError, "Argument parsing failed");
+ return NULL;
+ }
+
+ rv = get_volume_statvfs (volume_name, server_name, &buf);
+ closelog ();
+ if(rv==0)
+ return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i}","f_bsize",buf.f_bsize,"f_frsize",buf.f_frsize,"f_blocks",buf.f_blocks,"f_bfree",buf.f_bfree,"f_bavail",buf.f_bavail,"f_files",buf.f_files,"f_ffree",buf.f_ffree,"f_favail",buf.f_favail,"f_fsid",buf.f_fsid,"f_flag",buf.f_flag,"f_namemax",buf.f_namemax);
+ else{
+ if(rv == USAGE_ERROR)
+ PyErr_SetString(StatvfsError, "Usage error");
+ if(rv == GLFS_NEW_FAILURE)
+ PyErr_SetString(StatvfsError, "glfs_new() failed");
+ if(rv == GLFS_INIT_FAILURE)
+ PyErr_SetString(StatvfsError, "glfs_init() failed");
+ if(rv == GLFS_STATVFS_FAILURE)
+ PyErr_SetString(StatvfsError, "glfs_statvfs() failed");
+ return NULL;
+ }
+}
+
+
+static PyMethodDef glfspy_methods[] = {
+ { "statvfs", (PyCFunction)glfspy_statvfs, METH_VARARGS, NULL },
+ { NULL, NULL, 0, NULL }
+};
+
+
+PyMODINIT_FUNC initcapacity ()
+{
+ Py_InitModule3 ("capacity", glfspy_methods, "gluster gfapi top level extension module.");
+}
--
To view, visit http://gerrit.ovirt.org/26343
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib628b10c3b9743bb9fef5cbf41195e69ff851efd
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Darshan N <dnarayan(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: sp: Nest try-finally for temporary secure change
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: sp: Nest try-finally for temporary secure change
......................................................................
sp: Nest try-finally for temporary secure change
There were two instances where the same try-finally block was used for
both acquiring a lock and setting the pool as secure for a block of
code:
acquire lock
try:
set secure
code that needs both lock and secure state
finally:
set unsecure
release lock
This type of usage is incorrect. try-finally block should be used for
one change to ensure that the change is finally reverted, and to make
the intention of the code clear.
This patch use nested try-finally blocks, one for the lock, and one for
the secure state:
acquire lock
try:
set secure
try:
code that needs both lock and secure state
finally:
set unsecure
finally:
release lock
Because of the extra nesting, comments inside the nested code were
reformatted and missing punctuation was added.
I considered replacing the nested try-finally with a secured context
manager, but since the current code uses try-except-finally, using a
context manager would create an even deeper nesting or extracting some
new private methods. To keep minimal changes, I avoid this direction.
It seems that the secure state block can become smaller - some method
inside the secured block are @unsecured. I kept the secure block
semantics are they are now, and will check minimizing the secured block
in a later patch.
Change-Id: Ia9054063db0eeacd156a8e586681496515f80e2b
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M vdsm/storage/sp.py
1 file changed, 48 insertions(+), 48 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/55/23955/1
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index a020e1e..c26f7a8 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -566,40 +566,41 @@
fileUtils.createdir(self.poolPath)
self._acquireTemporaryClusterLock(msdUUID, leaseParams)
-
try:
self._setSecure()
- # Mark 'master' domain
- # We should do it before actually attaching this domain to the pool
- # During 'master' marking we create pool metadata and each attached
- # domain should register there
- self.createMaster(poolName, msd, masterVersion, leaseParams)
- self.__rebuild(msdUUID=msdUUID, masterVersion=masterVersion)
- # Attach storage domains to the storage pool
- # Since we are creating the pool then attach is done from the hsm
- # and not the spm therefore we must manually take the master domain
- # lock
- # TBD: create will receive only master domain and further attaches
- # should be done under SPM
-
- # Master domain was already attached (in createMaster),
- # no need to reattach
- for sdUUID in domList:
- # No need to attach the master
- if sdUUID != msdUUID:
- self.attachSD(sdUUID)
- except Exception:
- self.log.error("Create pool %s canceled ", poolName, exc_info=True)
try:
- fileUtils.cleanupdir(self.poolPath)
- self.__cleanupDomains(domList, msdUUID, masterVersion)
- except:
- self.log.error("Cleanup failed due to an unexpected error",
- exc_info=True)
- raise
- finally:
- self._setUnsecure()
+ # Mark 'master' domain. We should do it before actually
+ # attaching this domain to the pool During 'master' marking we
+ # create pool metadata and each attached domain should register
+ # there.
+ self.createMaster(poolName, msd, masterVersion, leaseParams)
+ self.__rebuild(msdUUID=msdUUID, masterVersion=masterVersion)
+ # Attach storage domains to the storage pool. Since we are
+ # creating the pool then attach is done from the hsm and not
+ # the spm therefore we must manually take the master domain
+ # lock.
+ # TBD: create will receive only master domain and further
+ # attaches should be done under SPM.
+ # Master domain was already attached (in createMaster), no need
+ # to reattach.
+ for sdUUID in domList:
+ # No need to attach the master
+ if sdUUID != msdUUID:
+ self.attachSD(sdUUID)
+ except Exception:
+ self.log.error("Create pool %s canceled ", poolName,
+ exc_info=True)
+ try:
+ fileUtils.cleanupdir(self.poolPath)
+ self.__cleanupDomains(domList, msdUUID, masterVersion)
+ except:
+ self.log.error("Cleanup failed due to an unexpected error",
+ exc_info=True)
+ raise
+ finally:
+ self._setUnsecure()
+ finally:
self._releaseTemporaryClusterLock(msdUUID)
self.stopMonitoringDomains()
@@ -697,29 +698,28 @@
# The host id must be set for createMaster(...).
self.id = hostId
temporaryLock = False
-
- # As in the create method we need to temporarily set the object
- # secure in order to change the domains map.
- # TODO: it is clear that reconstructMaster and create (StoragePool)
- # are extremely similar and they should be unified.
- self._setSecure()
-
try:
- self.createMaster(poolName, futureMaster, masterVersion,
- leaseParams)
- self.setMasterDomain(msdUUID, masterVersion)
+ # As in the create method we need to temporarily set the object
+ # secure in order to change the domains map.
+ # TODO: it is clear that reconstructMaster and create (StoragePool)
+ # are extremely similar and they should be unified.
+ self._setSecure()
+ try:
+ self.createMaster(poolName, futureMaster, masterVersion,
+ leaseParams)
+ self.setMasterDomain(msdUUID, masterVersion)
- for sdUUID in domDict:
- domDict[sdUUID] = domDict[sdUUID].capitalize()
+ for sdUUID in domDict:
+ domDict[sdUUID] = domDict[sdUUID].capitalize()
- # Add domain to domain list in pool metadata.
- self.log.info("Set storage pool domains: %s", domDict)
- self._backend.setDomainsMap(domDict)
+ # Add domain to domain list in pool metadata.
+ self.log.info("Set storage pool domains: %s", domDict)
+ self._backend.setDomainsMap(domDict)
- self.refresh(msdUUID=msdUUID, masterVersion=masterVersion)
+ self.refresh(msdUUID=msdUUID, masterVersion=masterVersion)
+ finally:
+ self._setUnsecure()
finally:
- self._setUnsecure()
-
if temporaryLock:
self._releaseTemporaryClusterLock(msdUUID)
self.stopMonitoringDomains()
--
To view, visit http://gerrit.ovirt.org/23955
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9054063db0eeacd156a8e586681496515f80e2b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
9 years, 11 months