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

Reply via email to