Federico Simoncelli has uploaded a new change for review. Change subject: sp: [wip] receive domains map in connectStoragePool ......................................................................
sp: [wip] receive domains map in connectStoragePool Change-Id: I393677f643a62e3711af2a3cfb8b4b9a5ce11c2d Signed-off-by: Federico Simoncelli <fsimo...@redhat.com> --- M vdsm/API.py M vdsm/BindingXMLRPC.py M vdsm/storage/hsm.py M vdsm/storage/sp.py 4 files changed, 243 insertions(+), 135 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/27/21427/1 diff --git a/vdsm/API.py b/vdsm/API.py index f91910c..90ba002 100644 --- a/vdsm/API.py +++ b/vdsm/API.py @@ -958,9 +958,12 @@ APIBase.__init__(self) self._UUID = UUID - def connect(self, hostID, scsiKey, masterSdUUID, masterVersion): - return self._irs.connectStoragePool(self._UUID, hostID, scsiKey, - masterSdUUID, masterVersion) + # FIXME: WIP patch, requires backward compatibility considerations + def connect(self, hostID, scsiKey, masterSdUUID, masterVersion, + domainsMap): + return self._irs.connectStoragePool( + self._UUID, hostID, scsiKey, masterSdUUID, masterVersion, + domainsMap) def connectStorageServer(self, domainType, connectionParams): return self._irs.connectStorageServer(domainType, self._UUID, diff --git a/vdsm/BindingXMLRPC.py b/vdsm/BindingXMLRPC.py index dd82b05..a1c8817 100644 --- a/vdsm/BindingXMLRPC.py +++ b/vdsm/BindingXMLRPC.py @@ -542,10 +542,12 @@ image = API.Image(imgUUID, spUUID, sdUUID) return image.download(methodArgs, volUUID) + # FIXME: WIP patch, requires backward compatibility considerations def poolConnect(self, spUUID, hostID, scsiKey, msdUUID, masterVersion, - options=None): + domainsMap=None, options=None): pool = API.StoragePool(spUUID) - return pool.connect(hostID, scsiKey, msdUUID, masterVersion) + return pool.connect(hostID, scsiKey, msdUUID, masterVersion, + domainsMap) def poolConnectStorageServer(self, domType, spUUID, conList, options=None): pool = API.StoragePool(spUUID) diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py index 3707528..56b24b4 100644 --- a/vdsm/storage/hsm.py +++ b/vdsm/storage/hsm.py @@ -981,8 +981,8 @@ poolName, masterDom, domList, masterVersion, leaseParams) @public - def connectStoragePool(self, spUUID, hostID, scsiKey, - msdUUID, masterVersion, options=None): + def connectStoragePool(self, spUUID, hostID, scsiKey, msdUUID, + masterVersion, domainsMap=None, options=None): """ Connect a Host to a specific storage pool. @@ -1010,11 +1010,12 @@ hostID, scsiKey))) with rmanager.acquireResource(STORAGE, HSM_DOM_MON_LOCK, rm.LockType.exclusive): - return self._connectStoragePool(spUUID, hostID, scsiKey, msdUUID, - masterVersion, options) + return self._connectStoragePool( + spUUID, hostID, scsiKey, msdUUID, masterVersion, + domainsMap, options) def _connectStoragePool(self, spUUID, hostID, scsiKey, msdUUID, - masterVersion, options=None): + masterVersion, domainsMap=None, options=None): misc.validateUUID(spUUID, 'spUUID') # TBD: To support multiple pool connection on single host, @@ -1055,7 +1056,13 @@ masterVersion=masterVersion) return - pool = sp.StoragePool(spUUID, self.domainMonitor, self.taskMng) + if domainsMap is not None: + pool = sp.StoragePool(spUUID, self.domainMonitor, + self.taskMng, domainsMap, masterVersion) + else: + pool = sp.StoragePoolLegacy( + spUUID, self.domainMonitor, self.taskMng) + res = pool.connect(hostID, scsiKey, msdUUID, masterVersion) if res: diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py index 46e8224..638891f 100644 --- a/vdsm/storage/sp.py +++ b/vdsm/storage/sp.py @@ -38,6 +38,7 @@ import fileSD import sd import misc +from misc import deprecated import fileUtils from vdsm.config import config from sdc import sdCache @@ -101,7 +102,7 @@ MAX_DOMAINS /= 48 -class StoragePool(Securable): +class StoragePoolBase(Securable): ''' StoragePool object should be relatively cheap to construct. It should defer any heavy lifting activities until the time it is really needed. @@ -113,7 +114,7 @@ lvExtendPolicy = config.get('irs', 'vol_extend_policy') def __init__(self, spUUID, domainMonitor, taskManager): - Securable.__init__(self) + super(StoragePoolBase, self).__init__() self._formatConverter = DefaultFormatConverter() self._domainsToUpgrade = [] @@ -132,10 +133,6 @@ self.domainMonitor = domainMonitor self._upgradeCallback = partial(StoragePool._upgradePoolDomain, proxy(self)) - - @unsecured - def getSpmLver(self): - return self.getMetaParam(PMDK_LVER) @unsecured def getSpmStatus(self): @@ -279,9 +276,8 @@ self.lver = int(oldlver) + 1 self.invalidateMetadata() - self.setMetaParams({ - PMDK_LVER: self.lver, - PMDK_SPM_ID: self.id}, __securityOverride=True) + self.updateSpmInfo(self.lver, self.id) + self._maxHostID = maxHostID # Upgrade the master domain now if needed @@ -487,10 +483,6 @@ sdUUID, msdUUID, masterVersion, exc_info=True) # Cleanup links to domains under /rhev/datacenter/poolName self.refresh(msdUUID, masterVersion) - - @unsecured - def getMasterVersion(self): - return self.getMetaParam(PMDK_MASTER_VER) # TODO: Remove or rename this function. @unsecured @@ -1361,21 +1353,6 @@ if os.path.exists(os.path.join(vms, vmUUID)): fileUtils.cleanupdir(os.path.join(vms, vmUUID)) - def setDescription(self, descr): - """ - Set storage pool description. - 'descr' - pool description - """ - if len(descr) > MAX_POOL_DESCRIPTION_SIZE: - raise se.StoragePoolDescriptionTooLongError() - - self.log.info("spUUID=%s descr=%s", self.spUUID, descr) - - if not misc.isAscii(descr) and not self.masterDomain.supportsUnicode(): - raise se.UnicodeArgumentException() - - self.setMetaParam(PMDK_POOL_DESCRIPTION, descr) - def extendVolume(self, sdUUID, volumeUUID, size, isShuttingDown=None): # This method is not exposed through the remote API but it's called # directly from the mailbox to implement the thin provisioning on @@ -1391,45 +1368,14 @@ return sdCache.produce(sdUUID) \ .produceVolume(imgUUID, volUUID).extendSize(int(newSize)) - @classmethod - def _getPoolMD(cls, domain): - # This might look disgusting but this makes it so that - # This is the only intrusion needed to satisfy the - # unholy union between pool and SD metadata - return DictValidator(domain._metadata._dict, SP_MD_FIELDS) - - @property - def _metadata(self): - return self._getPoolMD(self.masterDomain) - - @unsecured - def getDescription(self): - try: - return self.getMetaParam(PMDK_POOL_DESCRIPTION) - # There was a bug that cause pool description to - # disappear. Returning "" might be ugly but it keeps - # everyone happy. - except KeyError: - return "" - @unsecured def getVersion(self): return self.masterDomain.getVersion() @unsecured - def getSpmId(self): - spmid = self.getMetaParam(PMDK_SPM_ID) - if spmid != self.id or self.spmRole != SPM_FREE: - return spmid - - # If we claim to be the SPM we have to be really sure we are - self.invalidateMetadata() - return self.getMetaParam(PMDK_SPM_ID) - - @unsecured def getInfo(self): """ - Get storage pool info. + Get storage group info """ try: msdInfo = self.masterDomain.getInfo() @@ -1438,26 +1384,22 @@ raise se.StoragePoolMasterNotFound(self.spUUID, self.masterDomain.sdUUID) - try: - pmd = self._getPoolMD(self.masterDomain) - except Exception: - self.log.error("Pool metadata error", exc_info=True) - raise se.StoragePoolActionError(self.spUUID) - - poolInfo = { - 'type': msdInfo['type'], - 'name': pmd[PMDK_POOL_DESCRIPTION], - 'domains': domainListEncoder(pmd[PMDK_DOMAINS]), - 'master_uuid': self.masterDomain.sdUUID, - 'master_ver': pmd[PMDK_MASTER_VER], - 'lver': pmd[PMDK_LVER], - 'spm_id': pmd[PMDK_SPM_ID], - 'pool_status': 'uninitialized', - 'version': str(msdInfo['version']), - 'isoprefix': '', - 'pool_status': 'connected', + groupBaseInfo = { + "type": msdInfo["type"], + "name": "", + "domains": "", + "master_uuid": self.masterDomain.sdUUID, + "master_ver": 0, + "lver": LVER_INVALID, + "spm_id": SPM_ID_FREE, + "pool_status": "uninitialized", + "version": str(msdInfo["version"]), + "isoprefix": "", + "pool_status": "connected", } - return poolInfo + + groupBaseInfo.update(self.getGroupInfo()) + return groupBaseInfo @unsecured def getIsoDomain(self): @@ -1476,22 +1418,6 @@ return dom return None - def setMetaParams(self, params): - self._metadata.update(params) - - def setMetaParam(self, key, value): - """ - Set key:value in pool metadata file - """ - self._metadata[key] = value - - @unsecured - def getMetaParam(self, key): - """ - Get parameter from pool metadata file - """ - return self._metadata[key] - @unsecured def getMasterDomain(self, msdUUID, masterVersion): """ @@ -1506,32 +1432,8 @@ #Manager should start reconstructMaster if SPM. raise se.StoragePoolMasterNotFound(self.spUUID, msdUUID) - if not domain.isMaster(): - self.log.error("Requested master domain %s is not a master domain " - "at all", msdUUID) - raise se.StoragePoolWrongMaster(self.spUUID, msdUUID) - - pools = domain.getPools() - if (self.spUUID not in pools): - self.log.error("Requested master domain %s does not belong to pool" - " %s", msdUUID, self.spUUID) - raise se.StoragePoolWrongMaster(self.spUUID, msdUUID) - - version = self._getPoolMD(domain)[PMDK_MASTER_VER] - if version != int(masterVersion): - self.log.error("Requested master domain %s does not have expected " - "version %s it is version %s", - msdUUID, masterVersion, version) - raise se.StoragePoolWrongMaster(self.spUUID, msdUUID) - - self.log.debug("Master domain %s verified, version %s", msdUUID, - masterVersion) + self.checkMasterDomain(domain, masterVersion) return domain - - @unsecured - def invalidateMetadata(self): - if not self.spmRole == SPM_ACQUIRED: - self._metadata.invalidate() @unsecured @misc.samplingmethod @@ -1565,10 +1467,9 @@ @unsecured def getDomains(self, activeOnly=False): - return dict( - (sdUUID, status) for sdUUID, status in - self.getMetaParam(PMDK_DOMAINS).iteritems() - if not activeOnly or status == sd.DOM_ACTIVE_STATUS) + return dict((sdUUID, status) for sdUUID, status + in self.getDomainsMap().iteritems() + if not activeOnly or status == sd.DOM_ACTIVE_STATUS) def checkBackupDomain(self): domDict = self.getDomains(activeOnly=True) @@ -2012,3 +1913,198 @@ def getAllTasksInfo(self): return self.taskMng.getAllTasksInfo("spm") + + +class StoragePool(StoragePoolBase): + + def __init__(self, spUUID, domainMonitor, taskManager, domainsMap, + masterVersion): + super(StorageGroup, self) \ + .__init__(spUUID, domainMonitor, taskManager) + self.domainsMap = domainsMap + self.masterVersion = masterVersion + + @unsecured + def getSpmId(self): + spmid = self.masterDomain.getClusterLockOwnerId() + return SPM_ID_FREE if spmid is None else spmid + + @unsecured + def getGroupInfo(self): + return { + 'spm_id': self.getSpmId(), + 'master_ver': self.masterVersion, + } + + @unsecured + def getDomainsMap(self): + if self.domainsMap is None: + raise AttributeError("") + return self.domainsMap + + ### Deprecated Methods Section Begin ### + + @deprecated + @unsecured + def getSpmLver(self): + return LVER_INVALID + + @deprecated + @unsecured + def getMasterVersion(self): + return 0 + + @deprecated + @unsecured + def getDescription(self): + return "" + + @deprecated + def setDescription(self, description): + pass + + @deprecated + @unsecured + def checkMasterDomain(self, domain, masterVersion): + pass + + @deprecated + @unsecured + def invalidateMetadata(self): + pass + + @deprecated + @unsecured + def updateSpmInfo(self, lver, id): + pass + + ### Deprecated Methods Section End ### + + +class StoragePoolLegacy(StoragePoolBase): + + def __init__(self, spUUID, domainMonitor, taskManager): + super(StoragePool, self) \ + .__init__(spUUID, domainMonitor, taskManager) + + @classmethod + def _getPoolMD(cls, domain): + # This might look disgusting but this makes it so that + # This is the only intrusion needed to satisfy the + # unholy union between pool and SD metadata + return DictValidator(domain._metadata._dict, SP_MD_FIELDS) + + @property + def _metadata(self): + return self._getPoolMD(self.masterDomain) + + @unsecured + def getMetaParam(self, key): + """ + Get parameter from pool metadata file + """ + return self._metadata[key] + + def setMetaParams(self, params): + self._metadata.update(params) + + def setMetaParam(self, key, value): + """ + Set key:value in pool metadata file + """ + self._metadata[key] = value + + @unsecured + def getSpmLver(self): + return self.getMetaParam(PMDK_LVER) + + @unsecured + def getMasterVersion(self): + return self.getMetaParam(PMDK_MASTER_VER) + + @unsecured + def getDescription(self): + try: + return self.getMetaParam(PMDK_POOL_DESCRIPTION) + # There was a bug that cause pool description to + # disappear. Returning "" might be ugly but it keeps + # everyone happy. + except KeyError: + return "" + + def setDescription(self, descr): + """ + Set storage pool description. + 'descr' - pool description + """ + if len(descr) > MAX_POOL_DESCRIPTION_SIZE: + raise se.StoragePoolDescriptionTooLongError() + + self.log.info("spUUID=%s descr=%s", self.spUUID, descr) + + if not misc.isAscii(descr) and not self.masterDomain.supportsUnicode(): + raise se.UnicodeArgumentException() + + self.setMetaParam(PMDK_POOL_DESCRIPTION, descr) + + @unsecured + def checkMasterDomain(self, domain, masterVersion): + if not domain.isMaster(): + self.log.error("Requested master domain %s is not a master domain " + "at all", domain.sdUUID) + raise se.StoragePoolWrongMaster(self.spUUID, domain.sdUUID) + + pools = domain.getPools() + if (self.spUUID not in pools): + self.log.error("Requested master domain %s does not belong to pool" + " %s", domain.sdUUID, self.spUUID) + raise se.StoragePoolWrongMaster(self.spUUID, domain.sdUUID) + + version = self.getMasterVersion() + if version != int(masterVersion): + self.log.error("Requested master domain %s does not have expected " + "version %s it is version %s", + domain.sdUUID, masterVersion, version) + raise se.StoragePoolWrongMaster(self.spUUID, domain.sdUUID) + + self.log.debug("Master domain %s verified, version %s", domain.sdUUID, + masterVersion) + + @unsecured + def invalidateMetadata(self): + if not self.spmRole == SPM_ACQUIRED: + self._metadata.invalidate() + + @unsecured + def getSpmId(self): + spmid = self.getMetaParam(PMDK_SPM_ID) + if spmid != self.id or self.spmRole != SPM_FREE: + return spmid + + # If we claim to be the SPM we have to be really sure we are + self.invalidateMetadata() + return self.getMetaParam(PMDK_SPM_ID) + + @unsecured + def updateSpmInfo(self, lver, id): + self.setMetaParams({PMDK_LVER: lver, PMDK_SPM_ID: id}) + + @unsecured + def getGroupInfo(self): + try: + pmd = self._getPoolMD(self.masterDomain) + except Exception: + self.log.error("Pool metadata error", exc_info=True) + raise se.StoragePoolActionError(self.spUUID) + + return { + 'name': pmd[PMDK_POOL_DESCRIPTION], + 'domains': domainListEncoder(pmd[PMDK_DOMAINS]), + 'master_ver': pmd[PMDK_MASTER_VER], + 'lver': pmd[PMDK_LVER], + 'spm_id': pmd[PMDK_SPM_ID], + } + + @unsecured + def getDomainsMap(self): + return self.getMetaParam(PMDK_DOMAINS) -- To view, visit http://gerrit.ovirt.org/21427 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I393677f643a62e3711af2a3cfb8b4b9a5ce11c2d Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Federico Simoncelli <fsimo...@redhat.com> _______________________________________________ vdsm-patches mailing list vdsm-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches