]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/volumes/fs/operations/versions/__init__.py
7 from .subvolume_base
import SubvolumeBase
8 from .subvolume_attrs
import SubvolumeTypes
9 from .subvolume_v1
import SubvolumeV1
10 from .subvolume_v2
import SubvolumeV2
11 from .metadata_manager
import MetadataManager
12 from .op_sm
import SubvolumeOpSm
13 from ..template
import SubvolumeOpType
14 from ...exception
import MetadataMgrException
, OpSmException
, VolumeException
16 log
= logging
.getLogger(__name__
)
18 class SubvolumeLoader(object):
21 SUPPORTED_MODULES
= ['subvolume_v1.SubvolumeV1', 'subvolume_v2.SubvolumeV2']
24 self
.max_version
= SubvolumeLoader
.INVALID_VERSION
27 def _load_module(self
, mod_cls
):
28 mod_name
, cls_name
= mod_cls
.split('.')
29 mod
= importlib
.import_module('.versions.{0}'.format(mod_name
), package
='volumes.fs.operations')
30 return getattr(mod
, cls_name
)
32 def _load_supported_versions(self
):
33 for mod_cls
in SubvolumeLoader
.SUPPORTED_MODULES
:
34 cls
= self
._load
_module
(mod_cls
)
35 log
.info("loaded v{0} subvolume".format(cls
.version()))
36 if self
.max_version
is not None or cls
.version() > self
.max_version
:
37 self
.max_version
= cls
.version()
38 self
.versions
[cls
.version()] = cls
39 if self
.max_version
== SubvolumeLoader
.INVALID_VERSION
:
40 raise VolumeException(-errno
.EINVAL
, "no subvolume version available")
41 log
.info("max subvolume version is v{0}".format(self
.max_version
))
43 def _get_subvolume_version(self
, version
):
45 return self
.versions
[version
]
47 raise VolumeException(-errno
.EINVAL
, "subvolume class v{0} does not exist".format(version
))
49 def get_subvolume_object_max(self
, mgr
, fs
, vol_spec
, group
, subvolname
):
50 return self
._get
_subvolume
_version
(self
.max_version
)(mgr
, fs
, vol_spec
, group
, subvolname
)
52 def upgrade_to_v2_subvolume(self
, subvolume
):
53 # legacy mode subvolumes cannot be upgraded to v2
54 if subvolume
.legacy_mode
:
57 version
= int(subvolume
.metadata_mgr
.get_global_option('version'))
58 if version
>= SubvolumeV2
.version():
61 v1_subvolume
= self
._get
_subvolume
_version
(version
)(subvolume
.mgr
, subvolume
.fs
, subvolume
.vol_spec
, subvolume
.group
, subvolume
.subvolname
)
63 v1_subvolume
.open(SubvolumeOpType
.SNAP_LIST
)
64 except VolumeException
as ve
:
65 # if volume is not ready for snapshot listing, do not upgrade at present
66 if ve
.errno
== -errno
.EAGAIN
:
70 # v1 subvolumes with snapshots cannot be upgraded to v2
71 if v1_subvolume
.list_snapshots():
74 subvolume
.metadata_mgr
.update_global_section(MetadataManager
.GLOBAL_META_KEY_VERSION
, SubvolumeV2
.version())
75 subvolume
.metadata_mgr
.flush()
77 def upgrade_legacy_subvolume(self
, fs
, subvolume
):
78 assert subvolume
.legacy_mode
80 fs
.mkdirs(subvolume
.legacy_dir
, 0o700)
81 except cephfs
.Error
as e
:
82 raise VolumeException(-e
.args
[0], "error accessing subvolume")
83 subvolume_type
= SubvolumeTypes
.TYPE_NORMAL
85 initial_state
= SubvolumeOpSm
.get_init_state(subvolume_type
)
86 except OpSmException
as oe
:
87 raise VolumeException(-errno
.EINVAL
, "subvolume creation failed: internal error")
88 qpath
= subvolume
.base_path
.decode('utf-8')
89 # legacy is only upgradable to v1
90 subvolume
.init_config(SubvolumeV1
.version(), subvolume_type
, qpath
, initial_state
)
92 def get_subvolume_object(self
, mgr
, fs
, vol_spec
, group
, subvolname
, upgrade
=True):
93 subvolume
= SubvolumeBase(mgr
, fs
, vol_spec
, group
, subvolname
)
96 self
.upgrade_to_v2_subvolume(subvolume
)
97 version
= int(subvolume
.metadata_mgr
.get_global_option('version'))
98 subvolume_version_object
= self
._get
_subvolume
_version
(version
)(mgr
, fs
, vol_spec
, group
, subvolname
, legacy
=subvolume
.legacy_mode
)
99 subvolume_version_object
.metadata_mgr
.refresh()
100 subvolume_version_object
.clean_stale_snapshot_metadata()
101 return subvolume_version_object
102 except MetadataMgrException
as me
:
103 if me
.errno
== -errno
.ENOENT
and upgrade
:
104 self
.upgrade_legacy_subvolume(fs
, subvolume
)
105 return self
.get_subvolume_object(mgr
, fs
, vol_spec
, group
, subvolname
, upgrade
=False)
107 # log the actual error and generalize error string returned to user
108 log
.error("error accessing subvolume metadata for '{0}' ({1})".format(subvolname
, me
))
109 raise VolumeException(-errno
.EINVAL
, "error accessing subvolume metadata")
111 loaded_subvolumes
= SubvolumeLoader()
112 loaded_subvolumes
._load
_supported
_versions
()