[NEW PATCH] Don't override the rpm topdir macro settings (via gerrit-bot)
by Federico Simoncelli
New patch submitted by Federico Simoncelli (fsimonce(a)redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/826
commit 5c6e574aeff58e75121ed6e75acc37de7636acac
Author: Federico Simoncelli <fsimonce(a)redhat.com>
Date: Wed Aug 17 13:37:28 2011 +0000
Don't override the rpm topdir macro settings
Change-Id: Ia84386fb980745107c7d664900effcbc0bb2d18e
diff --git a/Makefile.am b/Makefile.am
index f51e595..35d18aa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,10 +19,7 @@ dist-hook:
.PHONY: srpm rpm
srpm: dist
- $(MKDIR_P) $(RPMTOP)/{RPMS,SRPMS,SOURCES,BUILD}
- rpmbuild -ts \
- --define="_topdir $(RPMTOP)" \
- --define="_sourcedir $(PWD)" $(DIST_ARCHIVES)
+ rpmbuild -ts $(DIST_ARCHIVES)
rpm: dist
- rpmbuild --define="_topdir $(RPMTOP)" -ta $(DIST_ARCHIVES)
+ rpmbuild -ta $(DIST_ARCHIVES)
12 years, 7 months
[NEW PATCH] Rewrote the _filterXmlChars after a code review. Using constant to generate restricted characters only once and a little speed improvment when returning the filtered string. (via gerrit-bot)
by ghammer@redhat.com
New patch submitted by Gal Hammer (ghammer(a)redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/907
commit 49d2002ff2009ed199b978d6d7088aa529a16231
Author: Gal Hammer <ghammer(a)redhat.com>
Date: Wed Sep 7 14:57:39 2011 +0300
Rewrote the _filterXmlChars after a code review. Using constant to generate restricted characters only once and a little speed improvment when returning the filtered string.
Change-Id: I217bb9f440469ecb1c4195ca11368eb47aa5b77c
diff --git a/vdsm/guestIF.py b/vdsm/guestIF.py
index 2d9926d..462fcf3 100644
--- a/vdsm/guestIF.py
+++ b/vdsm/guestIF.py
@@ -26,22 +26,26 @@ from config import config
import utils
import constants
+__RESTRICTED_CHARS = set(range(8+1)).union(
+ set(range(0xB,0xC+1))).union(
+ set(range(0xE,0x1F+1))).union(
+ set(range(0x7F,0x84+1))).union(
+ set(range(0x86,0x9F+1)))
+
def _filterXmlChars(u):
"""
- Filter out restarted xml chars from unicode string
+ Filter out restarted xml chars from unicode string. Not using
+ Python's xmlcharrefreplace because it accepts '\x01', which
+ the spec frown upon.
Set taken from http://www.w3.org/TR/xml11/#NT-RestrictedChar
"""
- restricted = set(range(8+1)).union(
- set(range(0xB,0xC+1))).union(
- set(range(0xE,0x1F+1))).union(
- set(range(0x7F,0x84+1))).union(
- set(range(0x86,0x9F+1)))
+
def maskRestricted(c):
- if ord(c) in restricted: return '?'
+ if ord(c) in __RESTRICTED_CHARS: return '?'
else: return c
- return ''.join([maskRestricted(c) for c in u])
+ return ''.join(maskRestricted(c) for c in u)
class GuestAgent (threading.Thread):
def __init__(self, socketName, log, user='Unknown', ips='', connect=True):
12 years, 7 months
[NEW PATCH] BZ#735932 vds_bootstrap: catch IOError when no /etc/redhat-release (via gerrit-bot)
by Dan Kenigsberg
New patch submitted by Dan Kenigsberg (danken(a)redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/916
commit db506acf35f155d2300d3774e78d7298f2a476e2
Author: Dan Kenigsberg <danken(a)redhat.com>
Date: Thu Sep 8 15:09:31 2011 +0300
BZ#735932 vds_bootstrap: catch IOError when no /etc/redhat-release
Former patch for this bug fails measerably on RHEL hosts.
Change-Id: I02d7734ee38b832038129b7e386fe60aa98011ad
diff --git a/vdsm_reg/deployUtil.py.in b/vdsm_reg/deployUtil.py.in
index 81020bb..d5ef3d8 100644
--- a/vdsm_reg/deployUtil.py.in
+++ b/vdsm_reg/deployUtil.py.in
@@ -356,14 +356,14 @@ def getOSVersion():
"""
s = ''
- for f in ('/etc/rhev-hypervisor-release', '/etc/redhat-release',
- '/etc/fedora-release'):
- try:
- s = file(f).read()
- except OSError:
- pass
-
try:
+ for f in ('/etc/rhev-hypervisor-release', '/etc/redhat-release',
+ '/etc/fedora-release'):
+ try:
+ s = file(f).read()
+ except (OSError, IOError):
+ pass
+
return islice(dropwhile(lambda x: x != 'release', s.split()),
1, 2).next()
except:
12 years, 7 months
[NEW PATCH] A new JSON-based protocol with the guest's agent. (via gerrit-bot)
by ghammer@redhat.com
New patch submitted by Gal Hammer (ghammer(a)redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/807
commit 9408893fbb8937250e93df8fa99a5d4b22d713bc
Author: Gal Hammer <ghammer(a)redhat.com>
Date: Wed Aug 10 13:26:31 2011 +0300
A new JSON-based protocol with the guest's agent.
Change-Id: Ie6096b326cc58879c8f63b72e32586657fffeca0
diff --git a/vdsm/clientIF.py b/vdsm/clientIF.py
index c5169a4..27eb973 100644
--- a/vdsm/clientIF.py
+++ b/vdsm/clientIF.py
@@ -269,7 +269,6 @@ class clientIF:
(self.desktopLogin, 'desktopLogin'),
(self.desktopLogoff, 'desktopLogoff'),
(self.desktopLock, 'desktopLock'),
- (self.sendHcCmdToDesktop, 'sendHcCmdToDesktop'),
(self.hibernate, 'hibernate'),
(self.monitorCommand, 'monitorCommand'),
(self.addNetwork, 'addNetwork'),
@@ -815,20 +814,6 @@ class clientIF:
else:
return errCode['nonresp']
- def sendHcCmdToDesktop (self, vmId, message):
- """
- Send a command to the guest agent (depricated).
- """
- try:
- vm = self.vmContainer[vmId]
- except KeyError:
- return errCode['noVM']
- vm.guestAgent.sendHcCmdToDesktop(message)
- if vm.guestAgent.isResponsive():
- return {'status': doneCode}
- else:
- return errCode['nonresp']
-
# take a rough estimate on how much free mem is available for new vm
# memTotal = memFree + memCached + mem_used_by_non_qemu + resident .
# simply returning (memFree + memCached) is not good enough, as the
diff --git a/vdsm/guestIF.py b/vdsm/guestIF.py
index a648dec..8ccf15b 100644
--- a/vdsm/guestIF.py
+++ b/vdsm/guestIF.py
@@ -2,6 +2,7 @@ import traceback, logging, threading
import time
import socket
import struct
+import json
from config import config
import utils
import constants
@@ -23,36 +24,6 @@ def _filterXmlChars(u):
return ''.join([maskRestricted(c) for c in u])
-
-class guestMType:
- powerup=1
- powerdown=2
- heartbeat=3
- guestName=4
- guestOs=5
- IPAddresses=6
- lastSessionMessage=7
- userInfo=8
- newApp=9
- flushApps=10
- sessionLock=12
- sessionUnlock=13
- sessionLogoff=14
- sessionLogon=15
- agentCmd = 16 # obsolete
- agentUninstalled = 17
- sessionStartup = 18
- sessionShutdown = 19
-
-class protocolMtype:
- register, unregister, forward = range(1, 4)
- error = 0x80000001
-
-
-headerLength = 3
-wordSize = 4
-headerLengthBytes = headerLength * wordSize
-
class GuestAgent (threading.Thread):
def __init__(self, socketName, log, user='Unknown', ips='', connect=True):
self.log = log
@@ -64,12 +35,6 @@ class GuestAgent (threading.Thread):
'session': 'Unknown', 'appsList': []}
self._agentTimestamp = 0
- # A temporary storage to hold the guest's application list during an
- # update from the guest. Will be obselete if a new virtual channel
- # (that can handle large messages) will be implemented and used.
- self._tempAppsList = []
- self._firstAppsList = True
-
threading.Thread.__init__(self)
if connect:
self.start()
@@ -88,109 +53,66 @@ class GuestAgent (threading.Thread):
time.sleep(1)
return False
- #The protocol envelope:
- #DWORD(32Bit) - ChannelID
- #DWORD(32Bit) - Action/Cmd
- # 1 - Register (to receive ChannelID events)
- # 2 - UnRegister (from ChannelID events)
- # 3 - Forward Message to channel
- # 0x80000001 - Error UnknownChannel
- #DWORD(32Bit) MessageLength(In Bytes)
- #message payload
- # Simple protocol at this point. Just a single byte
- # with enumeration of the event
- # 1 - PowerUp
- # 2 - PowerDown
- # 3 - HeartBeat
+ def _forward(self, cmd, args = {}):
+ args['__name__'] = cmd
+ message = (json.dumps(args) + '\n').encode('utf8')
+ self._sock.send(message)
+ self.log.log(logging.TRACE, 'sent %s', message)
- CHANNEL = 1
- def _forward(self, s):
- lens = len(s)
- t = struct.pack('>III%ds' % lens, self.CHANNEL,
- protocolMtype.forward, headerLengthBytes + lens, s)
- self._sock.send(t)
- self.log.log(logging.TRACE, 'sent %s', repr(t))
-
- def _parseHeader(self, header):
- channel, messageType, length = struct.unpack('>III', header)
- if channel != self.CHANNEL:
- self.log.error("Illegal channel id %d" % (channel))
- return 0
- if messageType != protocolMtype.forward:
- self.log.error("Unexpected message type " + str((channel, messageType, length)))
- return 0
- return length - headerLengthBytes
-
- def _parseBody(self, body):
- guestMessage, = struct.unpack('>I', body[:4])
- body = body[4:]
- self.log.log(logging.TRACE, 'guest message %s body %s',
- guestMessage, body)
+ def _handleMessage(self, message, args):
+ self.log.log(logging.TRACE, "Guest's message %s: %s", message, args)
if self.guestStatus == None:
self.guestStatus = 'Running'
- if guestMessage == guestMType.heartbeat:
+ if message == 'heartbeat':
self.guestStatus = 'Running'
- self.guestInfo['memUsage'] = int(body.strip())
- elif guestMessage == guestMType.powerup:
+ self.guestInfo['memUsage'] = int(args['free-ram'])
+ elif message == 'power-up':
self.guestStatus = 'Running'
- elif guestMessage == guestMType.powerdown:
+ elif message == 'power-down': # XXX: message is not send.
self.guestStatus = 'Powered down'
if self.guestInfo['username'] not in 'None': #in case powerdown event hit before logoff
self.guestInfo['lastUser'] = '' + self.guestInfo['username']
self.guestInfo['username'] = 'None'
self.guestInfo['lastLogout'] = time.time()
- elif guestMessage == guestMType.guestName:
- self.guestInfo['guestName'] = _filterXmlChars(unicode(body, 'utf8'))
- elif guestMessage == guestMType.guestOs:
- self.guestInfo['guestOs'] = _filterXmlChars(unicode(body, 'utf8'))
- elif guestMessage == guestMType.IPAddresses:
- guestIPs = body.strip().split()
- self.log.debug(str(guestIPs))
- self.guestInfo['guestIPs'] = _filterXmlChars(' '.join(guestIPs))
- elif guestMessage == guestMType.lastSessionMessage:
- lastSessionMessage = body
- self.log.debug(lastSessionMessage)
- if 'Logoff' in lastSessionMessage:
- self.guestInfo['lastUser'] = '' + self.guestInfo['username']
- self.guestInfo['username'] = 'None'
- self.guestInfo['lastLogout'] = time.time()
- elif guestMessage == guestMType.flushApps:
- if self._tempAppsList == self.guestInfo['appsList'] == []:
- self._firstAppsList = True
- else:
- self._firstAppsList = False
- self.guestInfo['appsList'] = self._tempAppsList
- self._tempAppsList = []
- elif guestMessage == guestMType.newApp:
- app = _filterXmlChars(unicode(body, 'utf8').strip())
- if app not in self._tempAppsList:
- self._tempAppsList.append(app)
- if self._firstAppsList:
- self.guestInfo['appsList'] = self._tempAppsList
- elif guestMessage == guestMType.userInfo:
- self.log.debug(body)
- currentUser = _filterXmlChars(unicode(body, 'utf8'))
+ elif message == 'host-name':
+ self.guestInfo['guestName'] = _filterXmlChars(args['name'])
+ elif message == 'os-version':
+ self.guestInfo['guestOs'] = _filterXmlChars(args['version'])
+ elif message == 'network-interfaces':
+ ips = ''
+ for iface in args['interfaces']:
+ ips += iface['inet'] + ' '
+ self.guestInfo['guestIPs'] = _filterXmlChars(ips)
+ elif message == 'applications':
+ apps = []
+ for app in args['applications']:
+ apps.append(_filterXmlChars(app))
+ self.guestInfo['appsList'] = apps
+ elif message == 'active-user':
+ currentUser = _filterXmlChars(args['name'])
if (currentUser != self.guestInfo['username']) and not (currentUser=='Unknown' and self.guestInfo['username']=='None'):
self.guestInfo['username'] = currentUser
self.guestInfo['lastLogin'] = time.time()
self.log.debug(repr(self.guestInfo['username']))
- elif guestMessage == guestMType.sessionLogon:
+ elif message == 'session-logon':
self.guestInfo['session'] = "UserLoggedOn"
- elif guestMessage == guestMType.sessionLock:
+ elif message == 'session-locked':
self.guestInfo['session'] = "Locked"
- elif guestMessage == guestMType.sessionUnlock:
+ elif message == 'session-unlock':
self.guestInfo['session'] = "Active"
- elif guestMessage == guestMType.sessionLogoff:
+ elif message == 'session-logoff':
self.guestInfo['session'] = "LoggedOff"
- elif guestMessage == guestMType.agentUninstalled:
+ elif message == 'uninstalled':
self.log.debug("RHEV agent was uninstalled.")
self.guestInfo['appsList'] = []
- elif guestMessage == guestMType.sessionStartup:
+ elif message == 'session-startup':
self.log.debug("Guest system is started or restarted.")
- elif guestMessage == guestMType.sessionShutdown:
+ elif message == 'session-shutdown':
self.log.debug("Guest system shuts down.")
+ elif message == 'disks-usage':
+ self.log.debug("Ignoring disks usages information...")
else:
- self.log.error('Unknown message type %s', guestMessage)
+ self.log.error('Unknown message type %s', message)
def stop (self):
self._stopped = True
@@ -220,7 +142,7 @@ class GuestAgent (threading.Thread):
def desktopLock(self):
try:
self.log.debug("desktopLock called")
- self._forward("lock screen")
+ self._forward("lock-screen")
except:
self.log.error(traceback.format_exc())
@@ -231,70 +153,77 @@ class GuestAgent (threading.Thread):
username = user + '@' + domain
else:
username = user
- username = username.encode('utf-8')
- password = password.encode('utf-8')
- s = struct.pack('>6sI%ds%ds' % (len(username), len(password) + 1),
- 'login', len(username), username, password)
- self._forward(s)
+ self._forward('login', { 'username' : username, "password" : password })
except:
self.log.error(traceback.format_exc())
def desktopLogoff (self, force):
try:
self.log.debug("desktopLogoff called")
- self._forward('log off')
+ self._forward('log-off')
except:
self.log.error(traceback.format_exc())
- def sendHcCmdToDesktop (self, cmd):
+ def desktopShutdown (self, timeout, msg):
try:
- self.log.debug("sendHcCmdToDesktop('%s')"%(cmd))
- self._forward(str(cmd))
+ self.log.debug("desktopShutdown called")
+ self._forward('shutdown', { 'timeout' : timeout, 'message' : msg })
except:
self.log.error(traceback.format_exc())
+ def _onChannelTimeout(self):
+ self.guestInfo['memUsage'] = 0
+ if self.guestStatus not in ("Powered down", "RebootInProgress"):
+ self.log.log(logging.TRACE, "Guest connection timed out")
+ self.guestStatus = None
+
READSIZE = 2**16
def _readBuffer(self):
- while not self._stopped:
- try:
- s = self._sock.recv(self.READSIZE)
- if s:
- self._buffer += s
- self._agentTimestamp = time.time()
- break
+ try:
+ s = self._sock.recv(self.READSIZE)
+ if s:
+ self._buffer += s
+ else:
time.sleep(1)
- except socket.timeout:
- # TODO move these specific bits out of here
- self.guestInfo['memUsage'] = 0
- if self.guestStatus not in ("Powered down", "RebootInProgress"):
- self.log.log(logging.TRACE, "Guest connection timed out")
- self.guestStatus = None
-
- def _readMessage(self):
- msg = None
- if len(self._buffer) >= headerLengthBytes:
- msglen = self._parseHeader(self._buffer[:headerLengthBytes])
- if len(self._buffer) >= headerLengthBytes + msglen:
- msg = self._buffer[headerLengthBytes:headerLengthBytes + msglen]
- self._buffer = self._buffer[headerLengthBytes + msglen:]
- return msg
-
- def _parseMessages(self):
- s = self._readMessage()
- while not self._stopped and s:
- self._parseBody(s)
- s = self._readMessage()
+ except socket.timeout:
+ self._onChannelTimeout()
+
+ def _readLine(self):
+ newline = self._buffer.find('\n')
+ while not self._stopped and newline < 0:
+ self._readBuffer()
+ newline = self._buffer.find('\n')
+ if newline >= 0:
+ newline += 1 # include the EOL char.
+ line = self._buffer[:newline]
+ self._buffer = self._buffer[newline:]
+ else:
+ line = None
+ return line
+
+ def _parseLine(self, line):
+ try:
+ args = json.loads(line.decode('utf8'))
+ name = args['__name__']
+ del args['__name__']
+ except:
+ self.log.exception("Error parsing: %s" % (line))
+ name = None
+ args = None
+ return (name, args)
def run(self):
self._stopped = False
try:
if not self._connect():
return
- self.sendHcCmdToDesktop('refresh')
+ self._forward('refresh')
self._buffer = ''
while not self._stopped:
- self._readBuffer()
- self._parseMessages()
+ (message, args) = self._parseLine(self._readLine())
+ if message:
+ self._agentTimestamp = time.time()
+ self._handleMessage(message, args)
except:
if not self._stopped:
self.log.error("Unexpected exception: " + traceback.format_exc())
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 941ea0a..ab88375 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -667,8 +667,7 @@ class Vm(object):
self._guestEventTime = now
self._guestEvent = 'Powering down'
self.log.debug('guestAgent shutdown called')
- guest_message = 'shutdown,' + timeout + ',' + message
- self.guestAgent.sendHcCmdToDesktop(guest_message)
+ self.guestAgent.desktopShutdown(timeout, message)
agent_timeout = int(timeout) + config.getint('vars', 'sys_shutdown_timeout')
timer = threading.Timer(agent_timeout, self._timedShutdown)
timer.start()
12 years, 7 months
[NEW PATCH] BZ#726970 iscsiadm: Return an appropriate error code to ISCSI_ERR_LOGIN_AUTH_FAILED (via gerrit-bot)
by David Naori
New patch submitted by David Naori (dnaori(a)redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/772
commit c2356c2f91d9652476c02a28477542e933d42737
Author: David Naori <dnaori(a)redhat.com>
Date: Mon Aug 1 15:32:08 2011 -0400
BZ#726970 iscsiadm: Return an appropriate error code to ISCSI_ERR_LOGIN_AUTH_FAILED
Change-Id: I2fa16bad0661ff06470e00e62bce27d98ed01f84
diff --git a/vdsm/storage/iscsi.py b/vdsm/storage/iscsi.py
index 1d5bf90..70697dc 100644
--- a/vdsm/storage/iscsi.py
+++ b/vdsm/storage/iscsi.py
@@ -246,6 +246,7 @@ discovery.sendtargets.iscsi.MaxRecvDataSegmentLength = 32768
# iscsiadm exit statuses
ISCSI_ERR_SESS_EXISTS = 15
+ISCSI_ERR_LOGIN_AUTH_FAILED = 24
log = logging.getLogger('Storage.iScsi')
@@ -472,7 +473,9 @@ def addiSCSINode(ip, port, iqn, tpgt, initiator, username=None, password=None):
# Finally instruct the iscsi initiator to login to the target
cmd = cmdt + ["-l", "-p", portal]
rc = misc.execCmd(cmd)[0]
- if rc not in (0, ISCSI_ERR_SESS_EXISTS):
+ if rc == ISCSI_ERR_LOGIN_AUTH_FAILED:
+ raise se.iSCSILoginAuthError(portal)
+ elif rc not in (0, ISCSI_ERR_SESS_EXISTS):
raise se.iSCSILoginError(portal)
except se.StorageException:
diff --git a/vdsm/storage/storage_exception.py b/vdsm/storage/storage_exception.py
index 1496bbc..8067189 100644
--- a/vdsm/storage/storage_exception.py
+++ b/vdsm/storage/storage_exception.py
@@ -913,6 +913,9 @@ class iSCSIDiscoveryError(StorageServeriSCSIError):
def __init__(self, portal, err):
self.value = "portal=%s, err=%s" % (portal, err)
+class iSCSILoginAuthError(StorageServeriSCSIError):
+ code = 476
+ message = "Failed to login to iSCSI node due to authorization failure"
#################################################
# LVM related Exceptions
#################################################
12 years, 7 months
Change in vdsm[master]: [WIP] Replace SPM domain locks with Sanlock
by ewarszaw@redhat.com
Eduardo Warszawski has posted comments on this change.
Change subject: [WIP] Replace SPM domain locks with Sanlock
......................................................................
Patch Set 2: I would prefer that you didn't submit this
(2 inline comments)
Only partial comments.
....................................................
File vdsm/storage/blockSD.py
Line 593: lvm.activateLVs(self.sdUUID, [sd.IDS])
Please don't activate here.
....................................................
File vdsm/storage/safelease.py
Line 93: class ClusterLock(object):
This is a redefinition of ClusterLock class.
Remove the 1st or change the name.
--
To view, visit http://gerrit.usersys.redhat.com/678
To unsubscribe, visit http://gerrit.usersys.redhat.com/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I3958a171e35d65544e0f2c3593daaf7daf8750ef
Gerrit-PatchSet: 2
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Gerrit-Reviewer: Ayal Baron
Gerrit-Reviewer: Eduardo Warszawski <ewarszaw(a)redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce(a)redhat.com>
Gerrit-Reviewer: Igor Lvovsky <ilvovsky(a)redhat.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi(a)redhat.com>
Gerrit-Reviewer: Yotam Oron <yoron(a)redhat.com>
12 years, 7 months
[NEW PATCH] BZ#733909 - get SPM id from lease instead of metadata (via gerrit-bot)
by smizrahi@redhat.com
New patch submitted by Saggi Mizrahi (smizrahi(a)redhat.com)
You can review this change at: http://gerrit.usersys.redhat.com/860
commit 9b85e68f8d39beb981f2204644313d6c4e3b1a54
Author: Saggi Mizrahi <smizrahi(a)redhat.com>
Date: Mon Aug 29 09:40:09 2011 +0300
BZ#733909 - get SPM id from lease instead of metadata
Metadata is cached and expensive to read and giving stale values to
management might cause undesired behaviour. This will cause VDSM to read
the spm owner directly from the lease which is safer and less expensive
then reading from metadata. Some places still rely on the metadata.
Those places either care about the metadata more then the actual value
or, like spmStart, must check consistency of both and use uncached
metadata anyways.
Change-Id: I582ae24aa843ad33e48a4cdd1e51b059355d132f
diff --git a/vdsm/storage/safelease.py b/vdsm/storage/safelease.py
index 107d304..814b5b5 100644
--- a/vdsm/storage/safelease.py
+++ b/vdsm/storage/safelease.py
@@ -26,8 +26,12 @@ import constants
import storage_exception as se
import threading
import logging
+import fileUtils
MAX_HOST_ID = 250
+ID_LEN = 16
+TIMESTAMP_LEN = 16
+TAG_LEN = ID_LEN + TIMESTAMP_LEN
class ClusterLock(object):
log = logging.getLogger("ClusterLock")
@@ -65,6 +69,19 @@ class ClusterLock(object):
self._leaseFailRetry = leaseFailRetry
self._ioOpTimeoutSec = ioOpTimeoutSec
+ def readTag(self):
+ with fileUtils.DirectFile(self._leaseFile, "dr") as f:
+ #Read 512 because you can't read less with direct io
+ tag = f.read(512)
+ try:
+ owner = int(tag[:ID_LEN])
+ except ValueError:
+ # When lease is free the tag is ------FREE-----
+ owner = -1
+ stamp = int(tag[ID_LEN:TAG_LEN], 16)
+
+ return owner, stamp
+
def acquire(self, hostID):
leaseTimeMs = self._leaseTimeSec * 1000
ioOpTimeoutMs = self._ioOpTimeoutSec * 1000
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 4fbf95f..056021e 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -495,6 +495,9 @@ class StoragePool:
finally:
self.id = None
+ def getClusterLockOwner(self):
+ self.log.warn("DASDASDASDASDASD %d", self.getMasterDomain()._clusterLock.readTag()[1])
+ return self.getMasterDomain()._clusterLock.readTag()[0]
def copyPoolMD(self, prevMd, newMD):
prevPoolMD = self._getPoolMD(prevMd)
@@ -1023,7 +1026,7 @@ class StoragePool:
info['domains'] = domainListEncoder(self.getDomains())
info['name'] = self.getDescription()
info['lver'] = self.getMetaParam(PMDK_LVER)
- info['spm_id'] = self.getMetaParam(PMDK_SPM_ID)
+ info['spm_id'] = self.getClusterLockOwner()
info['master_uuid'] = msdInfo['uuid']
info['master_ver'] = self.getMasterVersion()
info['version'] = str(self.getVersion())
@@ -1271,7 +1274,7 @@ class StoragePool:
try:
masterdomain = self.getMasterDomain()
self.invalidateMetadata()
- spmId = self.getMetaParam(PMDK_SPM_ID)
+ spmId = self.getClusterLockOwner()
domains = self.getDomains(activeOnly=True)
for dom in domains:
diff --git a/vdsm/storage/spm.py b/vdsm/storage/spm.py
index ae55e44..286fca0 100644
--- a/vdsm/storage/spm.py
+++ b/vdsm/storage/spm.py
@@ -720,7 +720,7 @@ class SPM:
pool = hsm.HSM.getPool(spUUID)
try:
lver = pool.getMetaParam(sp.PMDK_LVER)
- spmId = pool.getMetaParam(sp.PMDK_SPM_ID)
+ spmId = pool.getClusterLockOwner()
except se.LogicalVolumeRefreshError:
# This happens when we cannot read the MD LV
raise se.CannotRetrieveSpmStatus()
12 years, 7 months