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]: 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
Change in vdsm[master]: netinfo: Retrieve bonding options differing from defaults (WIP)
by osvoboda@redhat.com
Ondřej Svoboda has uploaded a new change for review.
Change subject: netinfo: Retrieve bonding options differing from defaults (WIP)
......................................................................
netinfo: Retrieve bonding options differing from defaults (WIP)
On failure, an empty dictionary is returned.
Tests are yet to be created.
Change-Id: Ief6d366b1b761627c7203cf236b75ef538af3e26
Bug-Url: https://bugzilla.redhat.com/987813
Signed-off-by: Ondřej Svoboda <osvoboda(a)redhat.com>
---
M lib/vdsm/netinfo.py
M tests/functional/networkTests.py
M tests/functional/supervdsmFuncTests.py
M vdsm/supervdsmServer
4 files changed, 53 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/56/24456/1
diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
index dbacb2f..fe48f81 100644
--- a/lib/vdsm/netinfo.py
+++ b/lib/vdsm/netinfo.py
@@ -41,7 +41,7 @@
from .ipwrapper import routeShowGateways, routeShowAllDefaultGateways
from . import libvirtconnection
from .ipwrapper import linkShowDev
-from .utils import anyFnmatch
+from .utils import anyFnmatch, execCmd, memoized, CommandPath
from .netconfpersistence import RunningConfig
@@ -68,9 +68,11 @@
_BONDING_LOADBALANCE_MODES = frozenset(('0', '2', '4', '5', '6'))
_IFCFG_ZERO_SUFFIXED = frozenset(
('IPADDR0', 'GATEWAY0', 'PREFIX0', 'NETMASK0'))
+_TEE_BINARY = CommandPath('tee', '/usr/bin/tee')
LIBVIRT_NET_PREFIX = 'vdsm-'
DUMMY_BRIDGE = ';vdsmdummy;'
+DUMMY_BOND = ';vdsmdummybond;'
DEFAULT_MTU = '1500'
REQUIRED_BONDINGS = frozenset(('bond0', 'bond1', 'bond2', 'bond3', 'bond4'))
@@ -531,9 +533,44 @@
return info
+@memoized
+def _getDefaultBondingOptions():
+ teeCmd = _TEE_BINARY.cmd
+
+ rc, _, err = execCmd([teeCmd, BONDING_MASTERS],
+ data='+' + DUMMY_BOND, sudo=True)
+ if rc:
+ raise OSError('Creating a reference bond failed: %s.', err)
+
+ try:
+ opts = bondOpts(DUMMY_BOND)
+ finally:
+ rc, _, _ = execCmd([teeCmd, BONDING_MASTERS],
+ data='-' + DUMMY_BOND, sudo=True)
+
+ return opts
+
+
+def _getBondingOptions(bond):
+ try:
+ defaults = _getDefaultBondingOptions()
+ opts = bondOpts(bond)
+
+ except Exception as e:
+ logging.exception('Reading bonding options failed.')
+ return {}
+
+ for key, val in dict(opts).iteritems():
+ if key in defaults and val == defaults[key]:
+ del opts[key]
+
+ return opts
+
+
def _bondinfo(link):
info = _devinfo(link)
- info.update({'hwaddr': link.address, 'slaves': slaves(link.name)})
+ info.update({'hwaddr': link.address, 'slaves': slaves(link.name),
+ 'options': _getBondingOptions(bond)})
return info
diff --git a/tests/functional/networkTests.py b/tests/functional/networkTests.py
index 695a29f..f2a785d 100644
--- a/tests/functional/networkTests.py
+++ b/tests/functional/networkTests.py
@@ -41,7 +41,7 @@
from vdsm.utils import RollbackContext
from vdsm.netinfo import (operstate, prefix2netmask, getRouteDeviceTo,
- getDhclientIfaces)
+ getDhclientIfaces, _getBondingOptions)
from vdsm import ipwrapper
from vdsm.utils import pgrep
@@ -1728,3 +1728,9 @@
NOCHK)
self.assertEqual(status, SUCCESS, msg)
self.assertNetworkDoesntExist(NETWORK_NAME)
+
+ def testGetBondingOptions(self):
+ # TODO: Create a bond with mode and miimon options set and check
+ # that no other options are returned.
+
+ _getBondingOptions('bond0')
diff --git a/tests/functional/supervdsmFuncTests.py b/tests/functional/supervdsmFuncTests.py
index 4596306..fa94291 100644
--- a/tests/functional/supervdsmFuncTests.py
+++ b/tests/functional/supervdsmFuncTests.py
@@ -37,3 +37,9 @@
self.dropPrivileges()
proxy = supervdsm.getProxy()
self.assertTrue(proxy.ping())
+
+ @testValidation.ValidateRunningAsRoot
+ def testDefaultBondingOptions(self):
+ proxy = supervdsm.getProxy()
+ print proxy.defaultBondingOptions()
+ raise Exception()
diff --git a/vdsm/supervdsmServer b/vdsm/supervdsmServer
index 21351c3..ce07dea 100755
--- a/vdsm/supervdsmServer
+++ b/vdsm/supervdsmServer
@@ -49,7 +49,7 @@
except ImportError:
_glusterEnabled = False
-from vdsm import utils
+from vdsm import netinfo, utils
from vdsm.tool import restore_nets
from parted_utils import getDevicePartedInfo as _getDevicePartedInfo
from md_utils import getMdDeviceUuidMap as _getMdDeviceUuidMap
--
To view, visit http://gerrit.ovirt.org/24456
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ief6d366b1b761627c7203cf236b75ef538af3e26
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Ondřej Svoboda <osvoboda(a)redhat.com>
9 years, 11 months
Change in vdsm[master]: vm: get rid of BoundedSemaphore around libvirt
by fromani@redhat.com
Francesco Romani has uploaded a new change for review.
Change subject: vm: get rid of BoundedSemaphore around libvirt
......................................................................
vm: get rid of BoundedSemaphore around libvirt
in the VM creation flow, we had a BoundedSemaphore
to throttle libvirt access and avoid congestion.
The ultimate purpose is to perform better.
However, since at least libvirt 0.10.x, avoiding
this semaphore leads to better performance.
Libvirt has more scalability improvement implemented
in later versions or planned, so this will improve
even further in the future.
Change-Id: I8a2038eadccee045e72dcf90cefe93286dab273b
Relates-To: https://bugzilla.redhat.com/861918
Signed-off-by: Francesco Romani <fromani(a)redhat.com>
---
M vdsm/vm.py
1 file changed, 0 insertions(+), 6 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/57/25857/1
diff --git a/vdsm/vm.py b/vdsm/vm.py
index c53f1d4..560ea32 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -1914,7 +1914,6 @@
"""
log = logging.getLogger("vm.Vm")
# limit threads number until the libvirt lock will be fixed
- _ongoingCreations = threading.BoundedSemaphore(4)
DeviceMapping = ((DISK_DEVICES, Drive),
(NIC_DEVICES, NetworkInterfaceDevice),
(SOUND_DEVICES, SoundDevice),
@@ -2300,8 +2299,6 @@
self.log.debug("Start")
try:
self.memCommit()
- self._ongoingCreations.acquire()
- self.log.debug("_ongoingCreations acquired")
self._vmCreationEvent.set()
try:
self._run()
@@ -2316,9 +2313,6 @@
raise
else:
self.log.info("Skipping errors on recovery", exc_info=True)
- finally:
- self._ongoingCreations.release()
- self.log.debug("_ongoingCreations released")
if ('migrationDest' in self.conf or 'restoreState' in self.conf) \
and self.lastStatus != 'Down':
--
To view, visit http://gerrit.ovirt.org/25857
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8a2038eadccee045e72dcf90cefe93286dab273b
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]: LiveMerge: Add Image.scanVolumes API
by alitke@redhat.com
Adam Litke has uploaded a new change for review.
Change subject: LiveMerge: Add Image.scanVolumes API
......................................................................
LiveMerge: Add Image.scanVolumes API
TODO:
- Revisit function naming
Change-Id: I9e50d7292b98b5dbf1f0978efe5f0de589b3dbc0
Signed-off-by: Adam Litke <alitke(a)redhat.com>
---
M client/vdsClient.py
M vdsm/API.py
M vdsm/BindingXMLRPC.py
M vdsm/storage/hsm.py
M vdsm/vm.py
5 files changed, 94 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/25918/1
diff --git a/client/vdsClient.py b/client/vdsClient.py
index 6344ed6..d818a5a 100644
--- a/client/vdsClient.py
+++ b/client/vdsClient.py
@@ -1385,6 +1385,19 @@
return image['status']['code'], image['status']['message']
return 0, image['uuid']
+ def imageScanVolumes(self, args):
+ spUUID = args[0]
+ sdUUID = args[1]
+ imgUUID = args[2]
+
+ if len(args) > 3:
+ chain = self.s.imageScanVolumes(spUUID, sdUUID, imgUUID, args[3])
+ else:
+ chain = self.s.imageScanVolumes(spUUID, sdUUID, imgUUID)
+ if chain['status']['code']:
+ return chain['status']['code'], chain['status']['message']
+ return 0, '\n'.join(chain['volumes'])
+
def mergeSnapshots(self, args):
sdUUID = args[0]
spUUID = args[1]
@@ -2411,6 +2424,14 @@
'Do it by collapse and copy the whole chain '
'(baseVolUUID->srcVolUUID)'
)),
+ 'scanVolumeChain': (serv.imageScanVolumes,
+ ('<spUUID> <sdUUID> <imgUUID> [<vmUUID>]',
+ 'Return the volumes that are actually in the '
+ 'image chain according to the hypervisor. '
+ 'If vmUUID is provided and the VM is runing, '
+ 'the VM will be queried. Otherwise the storage '
+ 'itself will be scanned.'
+ )),
'mergeSnapshots': (serv.mergeSnapshots,
('<sdUUID> <spUUID> <vmUUID> <imgUUID> <Ancestor '
'Image uuid> <Successor Image uuid> [<postZero>]',
diff --git a/vdsm/API.py b/vdsm/API.py
index ae959ef..7e3f18e 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -866,6 +866,20 @@
methodArgs, callback, self._spUUID, self._sdUUID, self._UUID,
volUUID)
+ def scanVolumes(self, vmUUID=None):
+ # If vmUUID is provided, we try to ask the running VM for the current
+ # state which is already synchronized with qemu. Otherwise, we use
+ # qemu-img on the volumes directly to determine current state.
+ if vmUUID:
+ try:
+ v = self._cif.vmContainer.get(vmUUID)
+ if v:
+ return v.getImageVolumes(self._UUID)
+ except KeyError:
+ pass
+ return self._irs.imageScanVolumes(self._spUUID, self._sdUUID,
+ self._UUID)
+
class LVMVolumeGroup(APIBase):
ctorArgs = ['lvmvolumegroupID']
diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py
index 259c262..d523957 100644
--- a/vdsm/BindingXMLRPC.py
+++ b/vdsm/BindingXMLRPC.py
@@ -601,6 +601,10 @@
image = API.Image(imgUUID, spUUID, sdUUID)
return image.download(methodArgs, volUUID)
+ def imageScanVolumes(self, spUUID, sdUUID, imgUUID, vmUUID=None):
+ image = API.Image(imgUUID, spUUID, sdUUID)
+ return image.scanVolumes(vmUUID)
+
def poolConnect(self, spUUID, hostID, scsiKey, msdUUID, masterVersion,
domainsMap=None, options=None):
pool = API.StoragePool(spUUID)
@@ -949,6 +953,7 @@
(self.imageSyncData, 'syncImageData'),
(self.imageUpload, 'uploadImage'),
(self.imageDownload, 'downloadImage'),
+ (self.imageScanVolumes, 'imageScanVolumes'),
(self.poolConnect, 'connectStoragePool'),
(self.poolConnectStorageServer, 'connectStorageServer'),
(self.poolCreate, 'createStoragePool'),
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 2e9dbe5..58fbc61 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1772,6 +1772,45 @@
misc.parseBool(postZero), misc.parseBool(force))
@public
+ def imageScanVolumes(self, spUUID, sdUUID, imgUUID):
+ argsStr = ("spUUID=%s, sdUUID=%s, imgUUID=%s" %
+ (spUUID, sdUUID, imgUUID))
+ vars.task.setDefaultException(se.StorageException("%s" % argsStr))
+
+ backingFiles = {}
+ leafVol = None
+ dom = sdCache.produce(sdUUID=sdUUID)
+ repoPath = os.path.join(self.storage_repository, dom.getPools()[0])
+ volclass = dom.getVolumeClass()
+ knownVols = volclass.getImageVolumes(repoPath, sdUUID, imgUUID)
+
+ imageResourcesNamespace = sd.getNamespace(sdUUID, IMAGE_NAMESPACE)
+ with rmanager.acquireResource(imageResourcesNamespace, imgUUID,
+ rm.LockType.shared):
+ # TODO: Do we need to ensure that they get deactivated also?
+ dom.activateVolumes(imgUUID, knownVols)
+
+ for volUUID in knownVols:
+ vol = dom.produceVolume(imgUUID, volUUID)
+ if vol.isLeaf():
+ leafVol = volUUID
+ qemuImgFormat = volume.fmt2str(vol.getFormat())
+ imgInfo = qemuImg.info(vol.volumePath, qemuImgFormat)
+ backingFile = imgInfo.get('backingfile')
+ if backingFile is not None:
+ # XXX: Is there a proper API for getting the volume UUID
+ # from a path string?
+ backingVol = os.path.basename(backingFile)
+ backingFiles[volUUID] = backingVol
+
+ volUUID = leafVol
+ retVolumes = [leafVol]
+ while backingFiles.get(volUUID) is not None:
+ volUUID = backingFiles[volUUID]
+ retVolumes.insert(0, volUUID)
+ return dict(volumes=retVolumes)
+
+ @public
def mergeSnapshots(self, sdUUID, spUUID, vmUUID, imgUUID, ancestor,
successor, postZero=False):
"""
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 6e3fbeb..0a68ee0 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -5275,6 +5275,21 @@
hooks.before_vm_migrate_destination(srcDomXML, self.conf)
return True
+ def getImageVolumes(self, imageID):
+ targetDrive = None
+ for drive in self._devices[DISK_DEVICES][:]:
+ try:
+ if drive.imageID == imageID:
+ targetDrive = drive
+ except AttributeError:
+ continue
+ if targetDrive is None:
+ return {'status': errCode['imageErr']}
+ volumes = []
+ for v in targetDrive.volumeChain:
+ volumes.append(v['volumeID'])
+ return {'status': doneCode, 'volumes': volumes}
+
# A little unrelated hack to make xml.dom.minidom.Document.toprettyxml()
# not wrap Text node with whitespace.
--
To view, visit http://gerrit.ovirt.org/25918
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9e50d7292b98b5dbf1f0978efe5f0de589b3dbc0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke(a)redhat.com>
9 years, 12 months
Change in vdsm[master]: logging: Enable all storage loggers
by Nir Soffer
Nir Soffer has uploaded a new change for review.
Change subject: logging: Enable all storage loggers
......................................................................
logging: Enable all storage loggers
Only loggers mentioned in logger.conf, or their child loggers are used
by the logging system. This make debugging the code much harder.
This patch enable 23 storage loggers by making them child loggers of the
Storage logger.
If we want to disable some loggers, the proper place to do it is in
logger.conf.
Change-Id: I1dd8cd29377b12dc290f90b7c6bf314d5624a830
Signed-off-by: Nir Soffer <nsoffer(a)redhat.com>
---
M vdsm/storage/blockSD.py
M vdsm/storage/clusterlock.py
M vdsm/storage/fileSD.py
M vdsm/storage/misc.py
M vdsm/storage/remoteFileHandler.py
M vdsm/storage/resourceManager.py
M vdsm/storage/storageServer.py
M vdsm/storage/task.py
M vdsm/storage/taskManager.py
M vdsm/storage/threadPool.py
10 files changed, 23 insertions(+), 23 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/23924/1
diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py
index 55bd796..35c4f45 100644
--- a/vdsm/storage/blockSD.py
+++ b/vdsm/storage/blockSD.py
@@ -277,7 +277,7 @@
class VGTagMetadataRW(object):
- log = logging.getLogger("storage.Metadata.VGTagMetadataRW")
+ log = logging.getLogger("Storage.Metadata.VGTagMetadataRW")
METADATA_TAG_PREFIX = "MDT_"
METADATA_TAG_PREFIX_LEN = len(METADATA_TAG_PREFIX)
@@ -320,7 +320,7 @@
"""
Block Storage Domain metadata implementation
"""
- log = logging.getLogger("storage.Metadata.LvMetadataRW")
+ log = logging.getLogger("Storage.Metadata.LvMetadataRW")
def __init__(self, vgName, lvName, offset, size):
self._size = size
diff --git a/vdsm/storage/clusterlock.py b/vdsm/storage/clusterlock.py
index f7e7fb6..83b2b9f 100644
--- a/vdsm/storage/clusterlock.py
+++ b/vdsm/storage/clusterlock.py
@@ -47,7 +47,7 @@
class SafeLease(object):
- log = logging.getLogger("SafeLease")
+ log = logging.getLogger("Storage.SafeLease")
lockUtilPath = config.get('irs', 'lock_util_path')
lockCmd = config.get('irs', 'lock_cmd')
@@ -137,7 +137,7 @@
self.log.debug("Cluster lock released successfully")
-initSANLockLog = logging.getLogger("initSANLock")
+initSANLockLog = logging.getLogger("Storage.initSANLock")
def initSANLock(sdUUID, idsPath, leasesPath):
@@ -154,7 +154,7 @@
class SANLock(object):
- log = logging.getLogger("SANLock")
+ log = logging.getLogger("Storage.SANLock")
_sanlock_fd = None
_sanlock_lock = threading.Lock()
@@ -290,7 +290,7 @@
class LocalLock(object):
- log = logging.getLogger("LocalLock")
+ log = logging.getLogger("Storage.LocalLock")
LVER = 0
diff --git a/vdsm/storage/fileSD.py b/vdsm/storage/fileSD.py
index 180a43f..98bb909 100644
--- a/vdsm/storage/fileSD.py
+++ b/vdsm/storage/fileSD.py
@@ -616,7 +616,7 @@
def scanDomains(pattern="*"):
- log = logging.getLogger("scanDomains")
+ log = logging.getLogger("Storage.scanDomains")
mntList = getMountsList(pattern)
diff --git a/vdsm/storage/misc.py b/vdsm/storage/misc.py
index 2c06af3..e464dcd 100644
--- a/vdsm/storage/misc.py
+++ b/vdsm/storage/misc.py
@@ -736,7 +736,7 @@
Supporting parameters or exception passing to all functions would
make the code much more complex for no reason.
"""
- _log = logging.getLogger("SamplingMethod")
+ _log = logging.getLogger("Storage.SamplingMethod")
def __init__(self, func):
self.__func = func
@@ -866,7 +866,7 @@
class Event(object):
def __init__(self, name, sync=False):
- self._log = logging.getLogger("Event.%s" % name)
+ self._log = logging.getLogger("Storage.Event.%s" % name)
self.name = name
self._syncRoot = threading.Lock()
self._registrar = {}
@@ -910,7 +910,7 @@
class OperationMutex(object):
- log = enableLogSkip(logging.getLogger("OperationMutex"),
+ log = enableLogSkip(logging.getLogger("Storage.OperationMutex"),
ignoreSourceFiles=[__file__, contextlib.__file__])
def __init__(self):
diff --git a/vdsm/storage/remoteFileHandler.py b/vdsm/storage/remoteFileHandler.py
index cacafbf..d5a4ff7 100644
--- a/vdsm/storage/remoteFileHandler.py
+++ b/vdsm/storage/remoteFileHandler.py
@@ -217,7 +217,7 @@
class PoolHandler(object):
- log = logging.getLogger("RepoFileHelper.PoolHandler")
+ log = logging.getLogger("Storage.RepoFileHelper.PoolHandler")
def __init__(self):
myRead, hisWrite = os.pipe()
diff --git a/vdsm/storage/resourceManager.py b/vdsm/storage/resourceManager.py
index 1be1450..64a5e86 100644
--- a/vdsm/storage/resourceManager.py
+++ b/vdsm/storage/resourceManager.py
@@ -168,7 +168,7 @@
"""
Internal request object, don't use directly
"""
- _log = logging.getLogger("ResourceManager.Request")
+ _log = logging.getLogger("Storage.ResourceManager.Request")
namespace = property(lambda self: self._namespace)
name = property(lambda self: self._name)
fullName = property(lambda self: "%s.%s" % (self._namespace, self._name))
@@ -190,7 +190,7 @@
# Because findCaller is expensive. We make sure it wll be printed
# before calculating it
- if logging.getLogger("ResourceManager.ResourceRef").\
+ if logging.getLogger("Storage.ResourceManager.ResourceRef").\
isEnabledFor(logging.WARN):
createdAt = misc.findCaller(ignoreSourceFiles=[__file__],
logSkipName="ResourceManager")
@@ -266,7 +266,7 @@
This object will auto release the referenced resource unless autorelease
is set to `False`
"""
- _log = logging.getLogger("ResourceManager.ResourceRef")
+ _log = logging.getLogger("Storage.ResourceManager.ResourceRef")
namespace = property(lambda self: self._namespace)
name = property(lambda self: self._name)
fullName = property(lambda self: "%s.%s" % (self._namespace, self._name))
@@ -354,7 +354,7 @@
This class is a singleton. use `getInstance()` to get the global instance
"""
- _log = logging.getLogger("ResourceManager")
+ _log = logging.getLogger("Storage.ResourceManager")
_namespaceValidator = re.compile(r"^[\w\d_-]+$")
_resourceNameValidator = re.compile(r"^[^\s.]+$")
@@ -721,7 +721,7 @@
class Owner(object):
- log = logging.getLogger('ResourceManager.Owner')
+ log = logging.getLogger('Storage.ResourceManager.Owner')
def __init__(self, ownerobject, raiseonfailure=False):
self.ownerobject = ownerobject
diff --git a/vdsm/storage/storageServer.py b/vdsm/storage/storageServer.py
index 786fba4..669dbd0 100644
--- a/vdsm/storage/storageServer.py
+++ b/vdsm/storage/storageServer.py
@@ -163,7 +163,7 @@
class MountConnection(object):
- log = logging.getLogger("StorageServer.MountConnection")
+ log = logging.getLogger("Storage.StorageServer.MountConnection")
localPathBase = "/tmp"
@property
@@ -514,7 +514,7 @@
class ConnectionAliasRegistrar(object):
- log = logging.getLogger("StorageServer.ConnectionAliasRegistrar")
+ log = logging.getLogger("Storage.StorageServer.ConnectionAliasRegistrar")
def __init__(self, persistDir):
self._aliases = {}
@@ -616,7 +616,7 @@
class ConnectionMonitor(object):
- _log = logging.getLogger("ConnectionMonitor")
+ _log = logging.getLogger("Storage.ConnectionMonitor")
TAG = "managed"
diff --git a/vdsm/storage/task.py b/vdsm/storage/task.py
index 4eff5c1..2837aa8 100644
--- a/vdsm/storage/task.py
+++ b/vdsm/storage/task.py
@@ -440,7 +440,7 @@
"metadataVersion": int
}
- log = logging.getLogger('TaskManager.Task')
+ log = logging.getLogger('Storage.TaskManager.Task')
def __init__(self, id, name="", tag="",
recovery=TaskRecoveryType.none,
diff --git a/vdsm/storage/taskManager.py b/vdsm/storage/taskManager.py
index ab7f898..0c54426 100644
--- a/vdsm/storage/taskManager.py
+++ b/vdsm/storage/taskManager.py
@@ -28,7 +28,7 @@
class TaskManager:
- log = logging.getLogger('TaskManager')
+ log = logging.getLogger('Storage.TaskManager')
def __init__(self,
tpSize=config.getfloat('irs', 'thread_pool_size'),
diff --git a/vdsm/storage/threadPool.py b/vdsm/storage/threadPool.py
index 2eb255e..f59b25c 100644
--- a/vdsm/storage/threadPool.py
+++ b/vdsm/storage/threadPool.py
@@ -25,7 +25,7 @@
accepts tasks that will be dispatched to the next available
thread."""
- log = logging.getLogger('Misc.ThreadPool')
+ log = logging.getLogger('Storage.ThreadPool')
def __init__(self, numThreads, waitTimeout=3, maxTasks=100):
@@ -175,7 +175,7 @@
""" Pooled thread class. """
- log = logging.getLogger('Misc.ThreadPool.WorkerThread')
+ log = logging.getLogger('Storage.ThreadPool.WorkerThread')
def __init__(self, pool):
--
To view, visit http://gerrit.ovirt.org/23924
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1dd8cd29377b12dc290f90b7c6bf314d5624a830
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer(a)redhat.com>
9 years, 12 months
Change in vdsm[master]: utils: add ovirt-node persistence functions
by Alon Bar-Lev
Alon Bar-Lev has uploaded a new change for review.
Change subject: utils: add ovirt-node persistence functions
......................................................................
utils: add ovirt-node persistence functions
Change-Id: Ib93af61a44a52c37faf92d6f6081babefa3a09aa
Signed-off-by: Alon Bar-Lev <alonbl(a)redhat.com>
---
M lib/vdsm/utils.py
1 file changed, 24 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/11/20811/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 78d055e..acb284c 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -877,3 +877,27 @@
logging.error("Panic: %s", msg, exc_info=True)
os.killpg(0, 9)
sys.exit(-3)
+
+
+@memoized
+def isOvirtNode():
+ return (
+ os.path.exists('/etc/rhev-hypervisor-release') or
+ glob.glob('/etc/ovirt-node-*-release')
+ )
+
+
+def ovirtNodePersist(files):
+ if isOvirtNode():
+ from ovirtnode import ovirtfunctions
+ ovirtfunctions.ovirt_store_config(files)
+
+
+def ovirtNodeUnpersist(files):
+ if isOvirtNode():
+ from ovirtnode import ovirtfunctions
+ todo = []
+ for f in files:
+ if ovirtfunctions.is_persisted(f):
+ todo.append(f)
+ ovirtfunctions.remove_config([todo])
--
To view, visit http://gerrit.ovirt.org/20811
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib93af61a44a52c37faf92d6f6081babefa3a09aa
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Alon Bar-Lev <alonbl(a)redhat.com>
9 years, 12 months
Change in vdsm[master]: drop ominous log for libvirt errors
by Dan Kenigsberg
Dan Kenigsberg has uploaded a new change for review.
Change subject: drop ominous log for libvirt errors
......................................................................
drop ominous log for libvirt errors
Patch http://gerrit.ovirt.org/13990 has introduced a log line whenever a
libvirt exception flows through our libvirtconnection.
E.g. Unknown libvirterror: ecode: 9 edom: 19 level: 2 message: operation
failed: network 'vdsm-ovirtmgmt' already exists...
The log line appears out of context and is repeated once its traceback
is properly caught.
Change-Id: Icd2a53ffee7fb78cb1c8d171093e93e233ed5ad4
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M lib/vdsm/libvirtconnection.py
1 file changed, 0 insertions(+), 4 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/17324/1
diff --git a/lib/vdsm/libvirtconnection.py b/lib/vdsm/libvirtconnection.py
index cdba57c..9891691 100644
--- a/lib/vdsm/libvirtconnection.py
+++ b/lib/vdsm/libvirtconnection.py
@@ -95,10 +95,6 @@
if killOnFailure:
log.error('taking calling process down.')
os.kill(os.getpid(), signal.SIGTERM)
- else:
- log.debug('Unknown libvirterror: ecode: %d edom: %d '
- 'level: %d message: %s', ecode, edom,
- e.get_error_level(), e.get_error_message())
raise
wrapper.__name__ = f.__name__
wrapper.__doc__ = f.__doc__
--
To view, visit http://gerrit.ovirt.org/17324
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icd2a53ffee7fb78cb1c8d171093e93e233ed5ad4
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
10 years
Change in vdsm[master]: spec: update sanlock dependencies
by Federico Simoncelli
Federico Simoncelli has uploaded a new change for review.
Change subject: spec: update sanlock dependencies
......................................................................
spec: update sanlock dependencies
Forcing some old fedora installations to update sanlock to the latest
version. This is mostly to address:
- wdmd: dynamically select working watchdog device
which makes it possible to run sanlock on hardware (generally laptops)
with multiple watchdogs.
Change-Id: Ia9a28d7bf23ab93781bdf3d8cf5769fe149fdeb4
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm.spec.in
1 file changed, 3 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/92/12292/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 38838ea..89da7af 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -107,7 +107,7 @@
Requires: device-mapper-multipath >= 0.4.9-52
Requires: e2fsprogs >= 1.41.12-11
Requires: kernel >= 2.6.32-279.9.1
-Requires: sanlock >= 2.3-4, sanlock-python
+Requires: sanlock >= 2.3-4
Requires: initscripts >= 9.03.31-2.el6_3.1
Requires: mom >= 0.3.0
Requires: selinux-policy-targeted >= 3.7.19-155
@@ -125,7 +125,7 @@
Requires: e2fsprogs >= 1.41.14
Requires: kernel >= 3.6
Requires: mom >= 0.3.0
-Requires: sanlock >= 2.4-2, sanlock-python
+Requires: sanlock >= 2.6-4
Requires: sed >= 4.2.1-10
Requires: selinux-policy-targeted >= 3.10.0-149
Requires: lvm2 >= 2.02.95
@@ -151,6 +151,7 @@
Requires: libselinux-python
Requires: %{name}-python = %{version}-%{release}
Requires: pyparted
+Requires: sanlock-python
Requires(post): /usr/sbin/saslpasswd2
Requires(post): /bin/hostname
--
To view, visit http://gerrit.ovirt.org/12292
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9a28d7bf23ab93781bdf3d8cf5769fe149fdeb4
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
10 years
Change in vdsm[master]: caps: Collect kdump status
by mperina@redhat.com
Martin Peřina has uploaded a new change for review.
Change subject: caps: Collect kdump status
......................................................................
caps: Collect kdump status
Adds kdump configuration status to caps module. The status will be
reported to engine in xml response of getCapabilities using boolean
key 'kdumpStatus'.
Change-Id: I68d7a2a24fdaad74255004af0f327197eaee65f2
BugUrl: https://bugzilla.redhat.com/970259
Signed-off-by: Martin Perina <mperina(a)redhat.com>
---
M vdsm/caps.py
M vdsm_api/vdsmapi-schema.json
2 files changed, 7 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/26/25926/1
diff --git a/vdsm/caps.py b/vdsm/caps.py
index b260d29..5b4c0cc 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -274,6 +274,10 @@
if os.path.exists(path)]
+def _getKdumpStatus():
+ return file('/sys/kernel/kexec_crash_loaded').read() == '1\n'
+
+
@utils.memoized
def getos():
if os.path.exists('/etc/rhev-hypervisor-release'):
@@ -386,6 +390,7 @@
config.getint('vars', 'extra_mem_reserve'))
caps['guestOverhead'] = config.get('vars', 'guest_ram_overhead')
caps['rngSources'] = _getRngSources()
+ caps['kdumpStatus'] = _getKdumpStatus()
return caps
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 1275ddb..ce71fb4 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -1032,7 +1032,8 @@
'HBAInventory': 'HbaInventory', 'vmTypes': ['VmType'],
'memSize': 'uint', 'reservedMem': 'uint',
'guestOverhead': 'uint', 'netConfigDirty': 'bool',
- 'rngSources': ['VmRngDeviceSource']}}
+ 'rngSources': ['VmRngDeviceSource'],
+ 'kdumpStatus': 'bool'}}
##
# @Host.getCapabilities:
--
To view, visit http://gerrit.ovirt.org/25926
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I68d7a2a24fdaad74255004af0f327197eaee65f2
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Martin Peřina <mperina(a)redhat.com>
10 years