Adam Litke has uploaded a new change for review.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
VolumeMetadata: move prepare and teardown
Change-Id: Iba0954ace3b1da5ea9afc41aeb6ea69a729fe29c Signed-off-by: Adam Litke alitke@redhat.com --- M vdsm/storage/blockVolume.py M vdsm/storage/fileVolume.py M vdsm/storage/volume.py 3 files changed, 117 insertions(+), 109 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/50/44050/1
diff --git a/vdsm/storage/blockVolume.py b/vdsm/storage/blockVolume.py index 0168d64..597e7ee 100644 --- a/vdsm/storage/blockVolume.py +++ b/vdsm/storage/blockVolume.py @@ -74,6 +74,8 @@ volume.VolumeMetadata.__init__(self, repoPath, sdUUID, imgUUID, volUUID) self.metaoff = None + self.lvmActivationNamespace = sd.getNamespace(self.sdUUID, + LVM_ACTIVATION_NAMESPACE)
def getMetadataId(self): """ @@ -332,6 +334,49 @@ lvs = lvm.lvsByTag(sdUUID, "%s%s" % (TAG_PREFIX_IMAGE, imgUUID)) return [lv.name for lv in lvs]
+ @logskip("ResourceManager") + def llPrepare(self, rw=False, setrw=False): + """ + Perform low level volume use preparation + + For the Block Volumes the actual LV activation is wrapped + into lvmActivation resource. It is being initialized by the + storage domain sitting on top of the encapsulating VG. + We just use it here. + """ + if setrw: + self.setrw(rw=rw) + access = rm.LockType.exclusive if rw else rm.LockType.shared + activation = rmanager.acquireResource(self.lvmActivationNamespace, + self.volUUID, access) + activation.autoRelease = False + + @classmethod + def teardown(cls, sdUUID, volUUID, justme=False): + """ + Deactivate volume and release resources. + Volume deactivation occurs as part of resource releasing. + If justme is false, the entire COW chain should be torn down. + """ + cls.log.info("Tearing down volume %s/%s justme %s" + % (sdUUID, volUUID, justme)) + lvmActivationNamespace = sd.getNamespace(sdUUID, + LVM_ACTIVATION_NAMESPACE) + rmanager.releaseResource(lvmActivationNamespace, volUUID) + if not justme: + try: + pvolUUID = _getVolumeTag(sdUUID, volUUID, TAG_PREFIX_PARENT) + except Exception as e: + # If storage not accessible or lvm error occurred + # we will failure to get the parent volume. + # We can live with it and still succeed in volume's teardown. + pvolUUID = volume.BLANK_UUID + cls.log.warn("Failure to get parent of volume %s/%s (%s)" + % (sdUUID, volUUID, e)) + + if pvolUUID != volume.BLANK_UUID: + cls.teardown(sdUUID=sdUUID, volUUID=pvolUUID, justme=False) +
class BlockVolume(volume.Volume): """ Actually represents a single volume (i.e. part of virtual disk). @@ -341,8 +386,6 @@ def __init__(self, repoPath, sdUUID, imgUUID, volUUID): md = self.MetadataClass(repoPath, sdUUID, imgUUID, volUUID) volume.Volume.__init__(self, md) - self.lvmActivationNamespace = sd.getNamespace(self.sdUUID, - LVM_ACTIVATION_NAMESPACE)
@property def metaoff(self): @@ -609,49 +652,6 @@ def shareVolumeRollback(cls, taskObj, volPath): cls.log.info("Volume rollback for volPath=%s", volPath) utils.rmFile(volPath) - - @logskip("ResourceManager") - def llPrepare(self, rw=False, setrw=False): - """ - Perform low level volume use preparation - - For the Block Volumes the actual LV activation is wrapped - into lvmActivation resource. It is being initialized by the - storage domain sitting on top of the encapsulating VG. - We just use it here. - """ - if setrw: - self.setrw(rw=rw) - access = rm.LockType.exclusive if rw else rm.LockType.shared - activation = rmanager.acquireResource(self.lvmActivationNamespace, - self.volUUID, access) - activation.autoRelease = False - - @classmethod - def teardown(cls, sdUUID, volUUID, justme=False): - """ - Deactivate volume and release resources. - Volume deactivation occurs as part of resource releasing. - If justme is false, the entire COW chain should be torn down. - """ - cls.log.info("Tearing down volume %s/%s justme %s" - % (sdUUID, volUUID, justme)) - lvmActivationNamespace = sd.getNamespace(sdUUID, - LVM_ACTIVATION_NAMESPACE) - rmanager.releaseResource(lvmActivationNamespace, volUUID) - if not justme: - try: - pvolUUID = _getVolumeTag(sdUUID, volUUID, TAG_PREFIX_PARENT) - except Exception as e: - # If storage not accessible or lvm error occurred - # we will failure to get the parent volume. - # We can live with it and still succeed in volume's teardown. - pvolUUID = volume.BLANK_UUID - cls.log.warn("Failure to get parent of volume %s/%s (%s)" - % (sdUUID, volUUID, e)) - - if pvolUUID != volume.BLANK_UUID: - cls.teardown(sdUUID=sdUUID, volUUID=pvolUUID, justme=False)
def getVolumeTag(self, tagPrefix): return self.md.getVolumeTag(tagPrefix) diff --git a/vdsm/storage/fileVolume.py b/vdsm/storage/fileVolume.py index 2dad91f..08e3f50 100644 --- a/vdsm/storage/fileVolume.py +++ b/vdsm/storage/fileVolume.py @@ -337,6 +337,26 @@ volList.append(volid) return volList
+ def llPrepare(self, rw=False, setrw=False): + """ + Make volume accessible as readonly (internal) or readwrite (leaf) + """ + volPath = self.getVolumePath() + + # Volumes leaves created in 2.2 did not have group writeable bit + # set. We have to set it here if we want qemu-kvm to write to old + # NFS volumes. + self.oop.fileUtils.copyUserModeToGroup(volPath) + + if setrw: + self.setrw(rw=rw) + if rw: + if not self.oop.os.access(volPath, os.R_OK | os.W_OK): + raise se.VolumeAccessError(volPath) + else: + if not self.oop.os.access(volPath, os.R_OK): + raise se.VolumeAccessError(volPath) +
class FileVolume(volume.Volume): """ Actually represents a single volume (i.e. part of virtual disk). @@ -488,26 +508,6 @@ procPool.utils.rmFile(volPath) procPool.utils.rmFile(cls.__metaVolumePath(volPath)) procPool.utils.rmFile(cls.MetadataClass._leaseVolumePath(volPath)) - - def llPrepare(self, rw=False, setrw=False): - """ - Make volume accessible as readonly (internal) or readwrite (leaf) - """ - volPath = self.getVolumePath() - - # Volumes leaves created in 2.2 did not have group writeable bit - # set. We have to set it here if we want qemu-kvm to write to old - # NFS volumes. - self.oop.fileUtils.copyUserModeToGroup(volPath) - - if setrw: - self.setrw(rw=rw) - if rw: - if not self.oop.os.access(volPath, os.R_OK | os.W_OK): - raise se.VolumeAccessError(volPath) - else: - if not self.oop.os.access(volPath, os.R_OK): - raise se.VolumeAccessError(volPath)
@classmethod def __putMetadata(cls, metaId, meta): diff --git a/vdsm/storage/volume.py b/vdsm/storage/volume.py index a098eb7..22f7ead 100644 --- a/vdsm/storage/volume.py +++ b/vdsm/storage/volume.py @@ -525,6 +525,56 @@ return apparentSize return req_size
+ def prepare(self, rw=True, justme=False, + chainrw=False, setrw=False, force=False): + """ + Prepare volume for use by consumer. + If justme is false, the entire COW chain is prepared. + Note: setrw arg may be used only by SPM flows. + """ + self.log.info("Volume: preparing volume %s/%s", + self.sdUUID, self.volUUID) + + if not force: + # Cannot prepare ILLEGAL volume + if not self.isLegal(): + raise se.prepareIllegalVolumeError(self.volUUID) + + if rw and self.isShared(): + if chainrw: + rw = False # Shared cannot be set RW + else: + raise se.SharedVolumeNonWritable(self) + + if (not chainrw and rw and self.isInternal() and setrw and + not self.recheckIfLeaf()): + raise se.InternalVolumeNonWritable(self) + + self.llPrepare(rw=rw, setrw=setrw) + self.updateInvalidatedSize() + + try: + if justme: + return True + pvol = self.produceParent() + if pvol: + pvol.prepare(rw=chainrw, justme=False, + chainrw=chainrw, setrw=setrw) + except Exception: + self.log.error("Unexpected error", exc_info=True) + self.teardown(self.sdUUID, self.volUUID) + raise + + return True + + @classmethod + def teardown(cls, sdUUID, volUUID, justme=False): + """ + Teardown volume. + If justme is false, the entire COW chain is teared down. + """ + pass +
class Volume(object): log = logging.getLogger('Storage.Volume') @@ -1091,53 +1141,11 @@
def prepare(self, rw=True, justme=False, chainrw=False, setrw=False, force=False): - """ - Prepare volume for use by consumer. - If justme is false, the entire COW chain is prepared. - Note: setrw arg may be used only by SPM flows. - """ - self.log.info("Volume: preparing volume %s/%s", - self.sdUUID, self.volUUID) - - if not force: - # Cannot prepare ILLEGAL volume - if not self.isLegal(): - raise se.prepareIllegalVolumeError(self.volUUID) - - if rw and self.isShared(): - if chainrw: - rw = False # Shared cannot be set RW - else: - raise se.SharedVolumeNonWritable(self) - - if (not chainrw and rw and self.isInternal() and setrw and - not self.recheckIfLeaf()): - raise se.InternalVolumeNonWritable(self) - - self.llPrepare(rw=rw, setrw=setrw) - self.updateInvalidatedSize() - - try: - if justme: - return True - pvol = self.produceParent() - if pvol: - pvol.prepare(rw=chainrw, justme=False, - chainrw=chainrw, setrw=setrw) - except Exception: - self.log.error("Unexpected error", exc_info=True) - self.teardown(self.sdUUID, self.volUUID) - raise - - return True + return self.md.prepare(rw, justme, chainrw, setrw, force)
@classmethod def teardown(cls, sdUUID, volUUID, justme=False): - """ - Teardown volume. - If justme is false, the entire COW chain is teared down. - """ - pass + cls.MetadataClass.teardown(sdUUID, volUUID, justme)
@classmethod def newMetadata(cls, metaId, sdUUID, imgUUID, puuid, size, format, type,
automation@ovirt.org has posted comments on this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Patch Set 1:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
automation@ovirt.org has posted comments on this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Patch Set 2:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
automation@ovirt.org has posted comments on this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Patch Set 3:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
automation@ovirt.org has posted comments on this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Patch Set 4:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
automation@ovirt.org has posted comments on this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Patch Set 5:
* Update tracker::IGNORE, no Bug-Url found * Check Bug-Url::WARN, no bug url found, make sure header matches 'Bug-Url: ' and is a valid url. * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.5', 'ovirt-3.4', 'ovirt-3.3'])
Adam Litke has abandoned this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Abandoned
better version already merged
gerrit-hooks has posted comments on this change.
Change subject: VolumeMetadata: move prepare and teardown ......................................................................
Patch Set 5:
* Update tracker: IGNORE, no Bug-Url found
vdsm-patches@lists.fedorahosted.org