import cephfs
from .subvolume_base import SubvolumeBase
-from ..op_sm import OpSm
+from .subvolume_attrs import SubvolumeTypes
+from .subvolume_v1 import SubvolumeV1
+from .subvolume_v2 import SubvolumeV2
+from .metadata_manager import MetadataManager
+from .op_sm import SubvolumeOpSm
+from ..template import SubvolumeOpType
from ...exception import MetadataMgrException, OpSmException, VolumeException
log = logging.getLogger(__name__)
class SubvolumeLoader(object):
INVALID_VERSION = -1
- SUPPORTED_MODULES = ['subvolume_v1.SubvolumeV1']
+ SUPPORTED_MODULES = ['subvolume_v1.SubvolumeV1', 'subvolume_v2.SubvolumeV2']
def __init__(self):
self.max_version = SubvolumeLoader.INVALID_VERSION
def get_subvolume_object_max(self, fs, vol_spec, group, subvolname):
return self._get_subvolume_version(self.max_version)(fs, vol_spec, group, subvolname)
+ def upgrade_to_v2_subvolume(self, subvolume):
+ # legacy mode subvolumes cannot be upgraded to v2
+ if subvolume.legacy_mode:
+ return
+
+ version = int(subvolume.metadata_mgr.get_global_option('version'))
+ if version >= SubvolumeV2.version():
+ return
+
+ v1_subvolume = self._get_subvolume_version(version)(subvolume.fs, subvolume.vol_spec, subvolume.group, subvolume.subvolname)
+ try:
+ v1_subvolume.open(SubvolumeOpType.SNAP_LIST)
+ except VolumeException as ve:
+ # if volume is not ready for snapshot listing, do not upgrade at present
+ if ve.errno == -errno.EAGAIN:
+ return
+ raise
+
+ # v1 subvolumes with snapshots cannot be upgraded to v2
+ if v1_subvolume.list_snapshots():
+ return
+
+ subvolume.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_VERSION, SubvolumeV2.version())
+ subvolume.metadata_mgr.flush()
+
def upgrade_legacy_subvolume(self, fs, subvolume):
assert subvolume.legacy_mode
try:
fs.mkdirs(subvolume.legacy_dir, 0o700)
except cephfs.Error as e:
raise VolumeException(-e.args[0], "error accessing subvolume")
- subvolume_type = SubvolumeBase.SUBVOLUME_TYPE_NORMAL
+ subvolume_type = SubvolumeTypes.TYPE_NORMAL
try:
- initial_state = OpSm.get_init_state(subvolume_type)
+ initial_state = SubvolumeOpSm.get_init_state(subvolume_type)
except OpSmException as oe:
raise VolumeException(-errno.EINVAL, "subvolume creation failed: internal error")
qpath = subvolume.base_path.decode('utf-8')
- subvolume.init_config(self.max_version, subvolume_type, qpath, initial_state)
+ # legacy is only upgradable to v1
+ subvolume.init_config(SubvolumeV1.version(), subvolume_type, qpath, initial_state)
def get_subvolume_object(self, fs, vol_spec, group, subvolname, upgrade=True):
subvolume = SubvolumeBase(fs, vol_spec, group, subvolname)
try:
subvolume.discover()
+ self.upgrade_to_v2_subvolume(subvolume)
version = int(subvolume.metadata_mgr.get_global_option('version'))
return self._get_subvolume_version(version)(fs, vol_spec, group, subvolname, legacy=subvolume.legacy_mode)
except MetadataMgrException as me: