From: Shyamsundar Ranganathan Date: Thu, 16 Jul 2020 01:03:58 +0000 (-0400) Subject: mgr/volumes: Avoid trashing retained subvolume on create errors X-Git-Tag: wip-pdonnell-testing-20200918.022351~489^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=e259185188ea2fd25d28eba149d3c33b322bfb26;p=ceph-ci.git mgr/volumes: Avoid trashing retained subvolume on create errors On any create or create_clone errors the entire subvolume was being removed. This should be conditional and remove only the incarnation if the subvolume was in the retained state. Signed-off-by: Shyamsundar Ranganathan --- diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py index 14397b59d40..9848acf8661 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py @@ -83,6 +83,26 @@ class SubvolumeV2(SubvolumeV1): return os.path.join(snap_base_path, uuid_str) + def _is_retained(self): + try: + self.metadata_mgr.refresh() + if self.state == SubvolumeStates.STATE_RETAINED: + return True + else: + raise VolumeException(-errno.EINVAL, "invalid state for subvolume '{0}' during create".format(self.subvolname)) + except MetadataMgrException as me: + if me.errno != -errno.ENOENT: + raise VolumeException(me.errno, "internal error while processing subvolume '{0}'".format(self.subvolname)) + return False + + def _remove_on_failure(self, subvol_path, retained): + if retained: + log.info("cleaning up subvolume incarnation with path: {0}".format(subvol_path)) + self._trash_dir(subvol_path) + else: + log.info("cleaning up subvolume with path: {0}".format(self.subvolname)) + self.remove() + def _set_incarnation_metadata(self, subvolume_type, qpath, initial_state): self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_TYPE, subvolume_type.value) self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_PATH, qpath) @@ -95,6 +115,7 @@ class SubvolumeV2(SubvolumeV1): except OpSmException as oe: raise VolumeException(-errno.EINVAL, "subvolume creation failed: internal error") + retained = self._is_retained() subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) try: self.fs.mkdirs(subvol_path, mode) @@ -102,21 +123,14 @@ class SubvolumeV2(SubvolumeV1): # persist subvolume metadata qpath = subvol_path.decode('utf-8') - try: - self.metadata_mgr.refresh() - if self.state == SubvolumeStates.STATE_RETAINED: - self._set_incarnation_metadata(subvolume_type, qpath, initial_state) - self.metadata_mgr.flush() - else: - raise VolumeException(-errno.EINVAL, "invalid state for subvolume '{0}' during create".format(self.subvolname)) - except MetadataMgrException as me: - if me.errno != -errno.ENOENT: - raise + if retained: + self._set_incarnation_metadata(subvolume_type, qpath, initial_state) + self.metadata_mgr.flush() + else: self.init_config(SubvolumeV2.VERSION, subvolume_type, qpath, initial_state) except (VolumeException, MetadataMgrException, cephfs.Error) as e: try: - log.info("cleaning up subvolume with path: {0}".format(self.subvolname)) - self.remove() + self._remove_on_failure(subvol_path, retained) except VolumeException as ve: log.info("failed to cleanup subvolume '{0}' ({1})".format(self.subvolname, ve)) @@ -134,6 +148,7 @@ class SubvolumeV2(SubvolumeV1): except OpSmException as oe: raise VolumeException(-errno.EINVAL, "clone failed: internal error") + retained = self._is_retained() subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8')) try: stx = self.fs.statx(source_subvolume.snapshot_data_path(snapname), @@ -153,22 +168,15 @@ class SubvolumeV2(SubvolumeV1): # persist subvolume metadata and clone source qpath = subvol_path.decode('utf-8') - try: - self.metadata_mgr.refresh() - if self.state == SubvolumeStates.STATE_RETAINED: - self._set_incarnation_metadata(subvolume_type, qpath, initial_state) - else: - raise VolumeException(-errno.EINVAL, "invalid state for subvolume '{0}' during clone".format(self.subvolname)) - except MetadataMgrException as me: - if me.errno != -errno.ENOENT: - raise + if retained: + self._set_incarnation_metadata(subvolume_type, qpath, initial_state) + else: self.metadata_mgr.init(SubvolumeV2.VERSION, subvolume_type.value, qpath, initial_state.value) self.add_clone_source(source_volname, source_subvolume, snapname) self.metadata_mgr.flush() except (VolumeException, MetadataMgrException, cephfs.Error) as e: try: - log.info("cleaning up subvolume with path: {0}".format(self.subvolname)) - self.remove() + self._remove_on_failure(subvol_path, retained) except VolumeException as ve: log.info("failed to cleanup subvolume '{0}' ({1})".format(self.subvolname, ve))