Liron Aravot has uploaded a new change for review. Change subject: adding the StorageDomain.upgradeVersion verb ......................................................................
adding the StorageDomain.upgradeVersion verb Change-Id: Id8fb87c6e04e48072ec90d07a0f4c7a61411a808 Signed-off-by: [email protected] <[email protected]> --- M client/vdsClient.py M vdsm/API.py M vdsm/rpc/BindingXMLRPC.py M vdsm/rpc/vdsmapi-schema.json M vdsm/storage/hsm.py M vdsm/storage/imageRepository/formatConverter.py M vdsm/storage/sp.py M vdsm/storage/storage_exception.py 8 files changed, 148 insertions(+), 24 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/78/42478/7 diff --git a/client/vdsClient.py b/client/vdsClient.py index e17ba76..c3628c5 100755 --- a/client/vdsClient.py +++ b/client/vdsClient.py @@ -682,6 +682,15 @@ return dom['status']['code'], dom['status']['message'] return 0, '' + def upgradeStorageDomainVersion(self, args): + sdUUID = args[0] + spUUID = args[1] + version = args[2] + dom = self.s.upgradeStorageDomainVersion(sdUUID, spUUID, version) + if dom['status']['code']: + return dom['status']['code'], dom['status']['message'] + return 0, '' + def detachStorageDomainAnyStoragePoolHsm(self, args): sdUUID = args[0] hostID = args[1] @@ -2521,6 +2530,12 @@ 'domain metadata is not modified to' 'reflect its detached.' )), + 'upgradeStorageDomainVersion': (serv.upgradeStorageDomainVersion, + ('<domain UUID> <pool UUID> <version>', + 'Upgrades a storage domain that is' + 'part of connected storage pool to' + 'the given version.' + )), 'detachStorageDomainAnyStoragePoolHsm': (serv.detachStorageDomainAnyStoragePoolHsm, ('<domain UUID>' '<hostId int>', diff --git a/vdsm/API.py b/vdsm/API.py index 3212616..3007d93 100644 --- a/vdsm/API.py +++ b/vdsm/API.py @@ -1023,6 +1023,10 @@ def detachAnyStoragePoolHsm(self, hostID): return self._irs.detachAnyStoragePoolHsm(self._UUID, hostID) + def upgradeVersion(self, storagepoolID, version): + return self._irs.upgradeStorageDomainVersion(self._UUID, storagepoolID, + version) + def extend(self, storagepoolID, devlist, force=False): return self._irs.extendStorageDomain(self._UUID, storagepoolID, devlist, force) diff --git a/vdsm/rpc/BindingXMLRPC.py b/vdsm/rpc/BindingXMLRPC.py index 70db4ed..5294e6a 100644 --- a/vdsm/rpc/BindingXMLRPC.py +++ b/vdsm/rpc/BindingXMLRPC.py @@ -640,6 +640,10 @@ domain = API.StorageDomain(sdUUID) return domain.detachAnyStoragePoolHsm(sdUUID, hostID) + def domainUpgradeVersion(self, sdUUID, spUUID, version): + domain = API.StorageDomain(sdUUID) + return domain.upgradeVersion(spUUID, version) + def domainDetachForced(self, sdUUID, spUUID, options=None): domain = API.StorageDomain(sdUUID) return domain.detach(spUUID, None, None, force=True) @@ -1089,7 +1093,8 @@ (self.domainDetachHsm, 'detachStorageDomainHsm'), (self.domainDetachAnyStoragePoolHsm, 'detachAnyStoragePoolHsm'), - (self.domainGetStoredVmsInfo, 'getStorageDomainStoredVmsInfo')) + (self.domainGetStoredVmsInfo, 'getStorageDomainStoredVmsInfo'), + (self.domainUpgradeVersion, 'upgradeStorageDomainVersion')) def getIrsMethods(self): return ((self.domainActivate, 'activateStorageDomain'), diff --git a/vdsm/rpc/vdsmapi-schema.json b/vdsm/rpc/vdsmapi-schema.json index 86cfb6e..7d514e3 100644 --- a/vdsm/rpc/vdsmapi-schema.json +++ b/vdsm/rpc/vdsmapi-schema.json @@ -5173,6 +5173,22 @@ 'data': {'storagedomainID': 'UUID', 'hostID' : 'int'}} ## +# @StorageDomain.upgradeVersion: +# +# Upgrades the StorageDomain version +# +# @storagedomainID: The UUID of the Storage Domain +# +# @storagepoolID: The UUID of the Storage Pool +# +# @version: The target version +# +# Since: 4.18.0 +## +{'command': {'class': 'StorageDomain', 'name': 'upgradeVersion'}, + 'data': {'storagedomainID': 'UUID', 'storagepoolID': 'UUID', 'version': 'int'}} + +## # @StorageDomain.extend: # # Extend a block-based Storage Domain onto more block devices. diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py index 95c4803..b1687da 100644 --- a/vdsm/storage/hsm.py +++ b/vdsm/storage/hsm.py @@ -844,6 +844,11 @@ pool.detachSDHsm(sdUUID) @public + def upgradeStorageDomainVersion(self, sdUUID, spUUID, version): + pool = self.getPool(spUUID) + pool.upgradeDomainFormat(sdUUID, version) + + @public def detachStorageDomainAnyStoragePoolHsm(self, sdUUID, hostID): """ Clears the StoragePool entry (Detach) in the given domain metadata diff --git a/vdsm/storage/imageRepository/formatConverter.py b/vdsm/storage/imageRepository/formatConverter.py index f5f8f6f..b88dbca 100644 --- a/vdsm/storage/imageRepository/formatConverter.py +++ b/vdsm/storage/imageRepository/formatConverter.py @@ -87,16 +87,28 @@ "for the domain %s", targetVersion, domain.sdUUID) +def v3_to_v4_DomainConvertor(repoPath, hostId, domain, isMsd): + domain.invalidateMetadata() + domain.setMetaParam(sd.DMDK_VERSION, 4) + + def v3DomainConverter(repoPath, hostId, domain, isMsd): + _v0_and_v2_to_v3v4DomainConverter(repoPath, hostId, domain, 3, isMsd) + + +def v0v2_to_v4DomainConverter(repoPath, hostId, domain, isMsd): + _v0_and_v2_to_v3v4DomainConverter(repoPath, hostId, domain, 4, isMsd) + + +def _v0_and_v2_to_v3v4DomainConverter(repoPath, hostId, domain, + targetVersion, isMsd): log = logging.getLogger('Storage.v3DomainConverter') - targetVersion = 3 currentVersion = domain.getVersion() log.debug("Starting conversion for domain %s from version %s " "to version %s", domain.sdUUID, currentVersion, targetVersion) - targetVersion = 3 currentVersion = domain.getVersion() # For block domains if we're upgrading from version 0 we need to first @@ -349,6 +361,9 @@ ('0', '2'): v2DomainConverter, ('0', '3'): v3DomainConverter, ('2', '3'): v3DomainConverter, + ('0', '4'): v0v2_to_v4DomainConverter, + ('2', '4'): v0v2_to_v4DomainConverter, + ('3', '4'): v3_to_v4_DomainConvertor, } diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py index 0202866..aaba2c0 100644 --- a/vdsm/storage/sp.py +++ b/vdsm/storage/sp.py @@ -167,25 +167,7 @@ return # This can never be the master - # Non data domain should not be upgraded - domClass = domain.getDomainClass() - if domClass != sd.DATA_DOMAIN: - self.log.debug("Domain `%s` is not a data domain it is an " - "%s domain, not upgrading", sdUUID, - domClass) - else: - domain.invalidateMetadata() - domVersion = domain.getVersion() - if domVersion > targetDomVersion: - self.log.critical("Found a domain with a more advanced" - " version then the master domain") - elif domVersion < targetDomVersion: - try: - self._convertDomain(domain, str(targetDomVersion)) - except: - self.log.warn("Could not upgrade domain `%s`", - sdUUID, exc_info=True) - return + self._upgradeDomainFormat(domain, targetDomVersion) self._domainsToUpgrade.remove(sdUUID) if len(self._domainsToUpgrade) == 0: @@ -196,6 +178,55 @@ unregister(self._upgradeCallback) except KeyError: pass + + @unsecured + def _upgradeDomainFormat(self, domain, targetDomVersion, + raiseExceptions=False): + domClass = domain.getDomainClass() + sdUUID = domain.sdUUID + # Non data domain should not be upgraded + if domClass != sd.DATA_DOMAIN: + if raiseExceptions: + raise se.CannotUpgradeNonDataDomain + + self.log.debug("Domain `%s` is not a data domain it is an " + "%s domain, not upgrading", sdUUID, + domClass) + else: + domain.invalidateMetadata() + domVersion = domain.getVersion() + if domVersion > targetDomVersion: + if raiseExceptions: + raise se.CannotUpgradeCurrVersionHigher + + self.log.critical("Found a domain with a more advanced" + " version then the target version n") + + elif domVersion < targetDomVersion: + try: + self._convertDomain(domain, str(targetDomVersion)) + except Exception as e: + if raiseExceptions: + raise e + self.log.warn("Could not upgrade domain `%s`", + sdUUID, exc_info=True) + return + + @unsecured + def upgradeDomainFormat(self, sdUUID, targetDomVersion): + self.validatePoolSD(sdUUID) + domain = sdCache.produce(sdUUID) + with rmanager.acquireResource(STORAGE, "upgrade_" + sdUUID, + rm.LockType.exclusive): + with rmanager.acquireResource(STORAGE, sdUUID, + rm.LockType.exclusive): + domain.acquireHostId(self.id) + try: + domain.acquireClusterLock(self.id) + self._upgradeDomainFormat(domain, targetDomVersion, + raiseExceptions=True) + finally: + domain.releaseClusterLock() def _updateDomainsRole(self): for sdUUID in self.getDomains(activeOnly=True): @@ -1058,7 +1089,8 @@ # Remember to get the sdUUID before upgrading because the object is # broken after the upgrade sdUUID = domain.sdUUID - isMsd = (self.masterDomain.sdUUID == sdUUID) + isMsd = self.masterDomain is not None and \ + self.masterDomain.sdUUID == sdUUID if targetFormat is None: targetFormat = self.getFormat() @@ -1096,7 +1128,21 @@ # Domain conversion requires the links to be present self._refreshDomainLinks(dom) - self._backend.setDomainRegularRole(dom) + + @unsecured + def _performDomainClusterLockOp(self, domain, releaseHostId, method, + *args, **kwargs): + try: + domain.acquireHostId(self.id) + try: + domain.acquireClusterLock(self.id) + method(*args, **kwargs) + finally: + domain.releaseClusterLock() + finally: + if releaseHostId: + domain.releaseHostId(self.id) + if dom.getDomainClass() == sd.DATA_DOMAIN: self._convertDomain(dom) diff --git a/vdsm/storage/storage_exception.py b/vdsm/storage/storage_exception.py index 2077964..50b522b 100644 --- a/vdsm/storage/storage_exception.py +++ b/vdsm/storage/storage_exception.py @@ -924,6 +924,24 @@ code = 443 +class CannotUpgradeNonDataDomain(StorageException): + def __init__(self, sdUUID): + self.value = "domain=%s" % sdUUID + self.message = ("As the domain `%s` is not a data domain, it is an " + "%s domain an upgrade isn't supported." % (sdUUID,)) + code = 444 + + +class CannotUpgradeCurrVersionHigher(StorageException): + def __init__(self, sdUUID, currVersion, targetVersion): + self.value = "sdUUID=%s, currentVersion=%s, targetVersion=%s" % \ + (sdUUID, currVersion, targetVersion) + self.message = ("As the domain `%s` version '%s' is higher then " + "the target version '%s' upgrade cannot be performed" % + (sdUUID, currVersion, targetVersion,)) + code = 445 + + ################################################# # Task Exceptions ################################################# -- To view, visit https://gerrit.ovirt.org/42478 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Id8fb87c6e04e48072ec90d07a0f4c7a61411a808 Gerrit-PatchSet: 7 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Liron Aravot <[email protected]> Gerrit-Reviewer: Jenkins CI RO Gerrit-Reviewer: Liron Aravot <[email protected]> Gerrit-Reviewer: gerrit-hooks <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
