Adam Litke has uploaded a new change for review. Change subject: StorageDomainManifest: move extend and extendVolume ......................................................................
StorageDomainManifest: move extend and extendVolume Change-Id: I0ad1769d7e4db6fc0883b37a67d071c278b96c8b Signed-off-by: Adam Litke <[email protected]> --- M vdsm/storage/blockSD.py M vdsm/storage/sd.py 2 files changed, 142 insertions(+), 118 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/66/42266/1 diff --git a/vdsm/storage/blockSD.py b/vdsm/storage/blockSD.py index e368e0b..caa7baf 100644 --- a/vdsm/storage/blockSD.py +++ b/vdsm/storage/blockSD.py @@ -404,6 +404,10 @@ metadata = selectMetadata(sdUUID) sd.StorageDomainManifest.__init__(self, sdUUID, domaindir, metadata) + # _extendlock is used to prevent race between + # VG extend and LV extend. + self._extendlock = threading.Lock() + try: self.logBlkSize = self.getMetaParam(DMDK_LOGBLKSIZE) self.phyBlkSize = self.getMetaParam(DMDK_PHYBLKSIZE) @@ -414,6 +418,15 @@ # Such domains supported only 512 sizes self.logBlkSize = 512 self.phyBlkSize = 512 + + def readMetadataMapping(self): + meta = self.getMetadata() + for key in meta.keys(): + if not DMDK_PV_REGEX.match(key): + del meta[key] + + self.log.info("META MAPPING: %s" % meta) + return meta def getReadDelay(self): stats = misc.readspeed(lvm.lvPath(self.sdUUID, sd.METADATA), 4096) @@ -444,6 +457,119 @@ lvm.activateLVs(self.sdUUID, [sd.IDS]) return lvm.lvPath(self.sdUUID, sd.IDS) + def extendVolume(self, volumeUUID, size, isShuttingDown=None): + self._extendlock.acquire() + try: + # FIXME: following line. + lvm.extendLV(self.sdUUID, volumeUUID, size) # , isShuttingDown) + finally: + self._extendlock.release() + + @classmethod + def getMetaDataMapping(cls, vgName, oldMapping={}): + firstDev, firstExtent = lvm.getFirstExt(vgName, sd.METADATA) + firstExtent = int(firstExtent) + if firstExtent != 0: + cls.log.error("INTERNAL: metadata ext is not 0") + raise se.MetaDataMappingError("vg %s: metadata extent is not the " + "first extent" % vgName) + + pvlist = list(lvm.listPVNames(vgName)) + + pvlist.remove(firstDev) + pvlist.insert(0, firstDev) + cls.log.info("Create: SORT MAPPING: %s" % pvlist) + + mapping = {} + devNum = len(oldMapping) + for dev in pvlist: + knownDev = False + for pvID, oldInfo in oldMapping.iteritems(): + if os.path.basename(dev) == oldInfo["guid"]: + mapping[pvID] = oldInfo + knownDev = True + break + + if knownDev: + continue + + pv = lvm.getPV(dev) + pvInfo = {} + pvInfo["guid"] = os.path.basename(pv.name) + pvInfo["uuid"] = pv.uuid + # this is another trick, it's not the + # the pestart value you expect, it's just + # 0, always + pvInfo["pestart"] = 0 + pvInfo["pecount"] = pv.pe_count + if devNum == 0: + mapOffset = 0 + else: + prevDevNum = devNum - 1 + try: + prevInfo = mapping["PV%d" % (prevDevNum,)] + except KeyError: + prevInfo = oldMapping["PV%d" % (prevDevNum,)] + + mapOffset = int(prevInfo["mapoffset"]) + \ + int(prevInfo["pecount"]) + + pvInfo["mapoffset"] = mapOffset + mapping["PV%d" % devNum] = pvInfo + devNum += 1 + + return mapping + + def updateMapping(self): + # First read existing mapping from metadata + with self._metadata.transaction(): + mapping = self.getMetaDataMapping(self.sdUUID, + self.readMetadataMapping()) + for key in set(self._metadata.keys() + mapping.keys()): + if DMDK_PV_REGEX.match(key): + if key in mapping: + self._metadata[key] = mapping[key] + else: + del self._metadata[key] + + @classmethod + def metaSize(cls, vgroup): + ''' Calc the minimal meta volume size in MB''' + # In any case the metadata volume cannot be less than 512MB for the + # case of 512 bytes per volume metadata, 2K for domain metadata and + # extent size of 128MB. In any case we compute the right size on line. + vg = lvm.getVG(vgroup) + minmetasize = (SD_METADATA_SIZE / sd.METASIZE * int(vg.extent_size) + + (1024 * 1024 - 1)) / (1024 * 1024) + metaratio = int(vg.extent_size) / sd.METASIZE + metasize = (int(vg.extent_count) * sd.METASIZE + + (1024 * 1024 - 1)) / (1024 * 1024) + metasize = max(minmetasize, metasize) + if metasize > int(vg.free) / (1024 * 1024): + raise se.VolumeGroupSizeError( + "volume group has not enough extents %s (Minimum %s), VG may " + "be too small" % (vg.extent_count, + (1024 * 1024) / sd.METASIZE)) + cls.log.info("size %s MB (metaratio %s)" % (metasize, metaratio)) + return metasize + + def extend(self, devlist, force): + with self._extendlock: + if self.getVersion() in VERS_METADATA_LV: + mapping = self.readMetadataMapping().values() + if len(mapping) + len(devlist) > MAX_PVS: + raise se.StorageDomainIsMadeFromTooManyPVs() + + knowndevs = set(multipath.getMPDevNamesIter()) + unknowndevs = set(devlist) - knowndevs + if unknowndevs: + raise se.InaccessiblePhysDev(unknowndevs) + + lvm.extendVG(self.sdUUID, devlist, force) + self.updateMapping() + newsize = self.metaSize(self.sdUUID) + lvm.extendLV(self.sdUUID, sd.METADATA, newsize) + class BlockStorageDomain(sd.StorageDomain): manifestClass = BlockStorageDomainManifest @@ -458,9 +584,6 @@ # block sizes. lvm.checkVGBlockSizes(sdUUID, (self.logBlkSize, self.phyBlkSize)) - # _extendlock is used to prevent race between - # VG extend and LV extend. - self._extendlock = threading.Lock() self.imageGarbageCollector() self._registerResourceNamespaces() self._lastUncachedSelftest = 0 @@ -495,24 +618,7 @@ @classmethod def metaSize(cls, vgroup): - ''' Calc the minimal meta volume size in MB''' - # In any case the metadata volume cannot be less than 512MB for the - # case of 512 bytes per volume metadata, 2K for domain metadata and - # extent size of 128MB. In any case we compute the right size on line. - vg = lvm.getVG(vgroup) - minmetasize = (SD_METADATA_SIZE / sd.METASIZE * int(vg.extent_size) + - (1024 * 1024 - 1)) / (1024 * 1024) - metaratio = int(vg.extent_size) / sd.METASIZE - metasize = (int(vg.extent_count) * sd.METASIZE + - (1024 * 1024 - 1)) / (1024 * 1024) - metasize = max(minmetasize, metasize) - if metasize > int(vg.free) / (1024 * 1024): - raise se.VolumeGroupSizeError( - "volume group has not enough extents %s (Minimum %s), VG may " - "be too small" % (vg.extent_count, - (1024 * 1024) / sd.METASIZE)) - cls.log.info("size %s MB (metaratio %s)" % (metasize, metaratio)) - return metasize + return cls.manifestClass.metaSize(vgroup) @classmethod def create(cls, sdUUID, domainName, domClass, vgUUID, storageType, @@ -657,87 +763,10 @@ @classmethod def getMetaDataMapping(cls, vgName, oldMapping={}): - firstDev, firstExtent = lvm.getFirstExt(vgName, sd.METADATA) - firstExtent = int(firstExtent) - if firstExtent != 0: - cls.log.error("INTERNAL: metadata ext is not 0") - raise se.MetaDataMappingError("vg %s: metadata extent is not the " - "first extent" % vgName) - - pvlist = list(lvm.listPVNames(vgName)) - - pvlist.remove(firstDev) - pvlist.insert(0, firstDev) - cls.log.info("Create: SORT MAPPING: %s" % pvlist) - - mapping = {} - devNum = len(oldMapping) - for dev in pvlist: - knownDev = False - for pvID, oldInfo in oldMapping.iteritems(): - if os.path.basename(dev) == oldInfo["guid"]: - mapping[pvID] = oldInfo - knownDev = True - break - - if knownDev: - continue - - pv = lvm.getPV(dev) - pvInfo = {} - pvInfo["guid"] = os.path.basename(pv.name) - pvInfo["uuid"] = pv.uuid - # this is another trick, it's not the - # the pestart value you expect, it's just - # 0, always - pvInfo["pestart"] = 0 - pvInfo["pecount"] = pv.pe_count - if devNum == 0: - mapOffset = 0 - else: - prevDevNum = devNum - 1 - try: - prevInfo = mapping["PV%d" % (prevDevNum,)] - except KeyError: - prevInfo = oldMapping["PV%d" % (prevDevNum,)] - - mapOffset = int(prevInfo["mapoffset"]) + \ - int(prevInfo["pecount"]) - - pvInfo["mapoffset"] = mapOffset - mapping["PV%d" % devNum] = pvInfo - devNum += 1 - - return mapping - - def updateMapping(self): - # First read existing mapping from metadata - with self._metadata.transaction(): - mapping = self.getMetaDataMapping(self.sdUUID, - self.readMetadataMapping()) - for key in set(self._metadata.keys() + mapping.keys()): - if DMDK_PV_REGEX.match(key): - if key in mapping: - self._metadata[key] = mapping[key] - else: - del self._metadata[key] + return cls.manifestClass.getMetaDataMapping(vgName, oldMapping) def extend(self, devlist, force): - with self._extendlock: - if self.getVersion() in VERS_METADATA_LV: - mapping = self.readMetadataMapping().values() - if len(mapping) + len(devlist) > MAX_PVS: - raise se.StorageDomainIsMadeFromTooManyPVs() - - knowndevs = set(multipath.getMPDevNamesIter()) - unknowndevs = set(devlist) - knowndevs - if unknowndevs: - raise se.InaccessiblePhysDev(unknowndevs) - - lvm.extendVG(self.sdUUID, devlist, force) - self.updateMapping() - newsize = self.metaSize(self.sdUUID) - lvm.extendLV(self.sdUUID, sd.METADATA, newsize) + self._manifest.extend(devlist, force) _lvTagMetaSlotLock = threading.Lock() @@ -822,13 +851,7 @@ (self.sdUUID, dev, ext)) def readMetadataMapping(self): - meta = self.getMetadata() - for key in meta.keys(): - if not DMDK_PV_REGEX.match(key): - del meta[key] - - self.log.info("META MAPPING: %s" % meta) - return meta + return self._manifest.readMetadataMapping() def getLeasesFileSize(self): lv = lvm.getLV(self.sdUUID, sd.LEASES) @@ -1325,12 +1348,7 @@ os.symlink(src, dst) def extendVolume(self, volumeUUID, size, isShuttingDown=None): - self._extendlock.acquire() - try: - # FIXME: following line. - lvm.extendLV(self.sdUUID, volumeUUID, size) # , isShuttingDown) - finally: - self._extendlock.release() + return self._manifest.extendVolume(volumeUUID, size, isShuttingDown) def refresh(self): self.refreshDirTree() diff --git a/vdsm/storage/sd.py b/vdsm/storage/sd.py index 4a89805..1f3ec36 100644 --- a/vdsm/storage/sd.py +++ b/vdsm/storage/sd.py @@ -317,8 +317,17 @@ return os.path.join(self.domaindir, DOMAIN_META_DATA) return None + def getMetadata(self): + """ + Unified Metadata accessor/mutator + """ + return self._metadata.copy() + def getMetaParam(self, key): return self._metadata[key] + + def getVersion(self): + return self.getMetaParam(DMDK_VERSION) class StorageDomain(object): @@ -502,7 +511,7 @@ exc_info=True) def getVersion(self): - return self.getMetaParam(DMDK_VERSION) + return self._manifest.getVersion() def getFormat(self): return str(self.getVersion()) @@ -778,10 +787,7 @@ pass def getMetadata(self): - """ - Unified Metadata accessor/mutator - """ - return self._metadata.copy() + return self._manifest.getMetadata() def setMetadata(self, newMetadata): # Backup old md (rotate old backup files) -- To view, visit https://gerrit.ovirt.org/42266 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0ad1769d7e4db6fc0883b37a67d071c278b96c8b Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Adam Litke <[email protected]> _______________________________________________ vdsm-patches mailing list [email protected] https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches
