From b8b0f1f3d1b57eec557dc82dfa96a81e2b1e41bf Mon Sep 17 00:00:00 2001 From: Xavi Hernandez Date: Wed, 19 Mar 2025 13:05:19 +0100 Subject: [PATCH] pybind/mgr: add option to set unicode normalization to a subvolume Add an option to explicitly set the unicode normalization form to use on a CephFS subvolume. Signed-off-by: Xavi Hernandez --- src/pybind/mgr/volumes/fs/operations/subvolume.py | 5 +++-- .../mgr/volumes/fs/operations/versions/subvolume_v1.py | 5 +++-- .../mgr/volumes/fs/operations/versions/subvolume_v2.py | 5 +++-- src/pybind/mgr/volumes/fs/volume.py | 7 +++++-- src/pybind/mgr/volumes/module.py | 6 ++++-- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/pybind/mgr/volumes/fs/operations/subvolume.py b/src/pybind/mgr/volumes/fs/operations/subvolume.py index 256c8d7607492..bac51a4289502 100644 --- a/src/pybind/mgr/volumes/fs/operations/subvolume.py +++ b/src/pybind/mgr/volumes/fs/operations/subvolume.py @@ -5,7 +5,7 @@ from .group import open_group from .template import SubvolumeOpType from .versions import loaded_subvolumes -def create_subvol(mgr, fs, vol_spec, group, subvolname, size, isolate_nspace, pool, mode, uid, gid, earmark): +def create_subvol(mgr, fs, vol_spec, group, subvolname, size, isolate_nspace, pool, mode, uid, gid, earmark, normalization): """ create a subvolume (create a subvolume with the max known version). @@ -19,10 +19,11 @@ def create_subvol(mgr, fs, vol_spec, group, subvolname, size, isolate_nspace, po :param uid: the user identifier :param gid: the group identifier :param earmark: metadata string to identify if subvolume is associated with nfs/smb + :param normalization: the unicode normalization form to use (nfd, nfc, nfkd or nfkc) :return: None """ subvolume = loaded_subvolumes.get_subvolume_object_max(mgr, fs, vol_spec, group, subvolname) - subvolume.create(size, isolate_nspace, pool, mode, uid, gid, earmark) + subvolume.create(size, isolate_nspace, pool, mode, uid, gid, earmark, normalization) def create_clone(mgr, fs, vol_spec, group, subvolname, pool, source_volume, source_subvolume, snapname): diff --git a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py index 3440ab108c857..019c2b878a9c6 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v1.py @@ -85,7 +85,7 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): """ Path to user data directory within a subvolume snapshot named 'snapname' """ return self.snapshot_path(snapname) - def create(self, size, isolate_nspace, pool, mode, uid, gid, earmark): + def create(self, size, isolate_nspace, pool, mode, uid, gid, earmark, normalization): subvolume_type = SubvolumeTypes.TYPE_NORMAL try: initial_state = SubvolumeOpSm.get_init_state(subvolume_type) @@ -104,7 +104,8 @@ class SubvolumeV1(SubvolumeBase, SubvolumeTemplate): 'data_pool': pool, 'pool_namespace': self.namespace if isolate_nspace else None, 'quota': size, - 'earmark': earmark + 'earmark': earmark, + 'normalization': normalization, } self.set_attrs(subvol_path, attrs) 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 bec271f659fbf..2c4d493ec2cbf 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/subvolume_v2.py @@ -154,7 +154,7 @@ class SubvolumeV2(SubvolumeV1): self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_PATH, qpath) self.metadata_mgr.update_global_section(MetadataManager.GLOBAL_META_KEY_STATE, initial_state.value) - def create(self, size, isolate_nspace, pool, mode, uid, gid, earmark): + def create(self, size, isolate_nspace, pool, mode, uid, gid, earmark, normalization): subvolume_type = SubvolumeTypes.TYPE_NORMAL try: initial_state = SubvolumeOpSm.get_init_state(subvolume_type) @@ -176,7 +176,8 @@ class SubvolumeV2(SubvolumeV1): 'data_pool': pool, 'pool_namespace': self.namespace if isolate_nspace else None, 'quota': size, - 'earmark': earmark + 'earmark': earmark, + 'normalization': normalization, } self.set_attrs(subvol_path, attrs) diff --git a/src/pybind/mgr/volumes/fs/volume.py b/src/pybind/mgr/volumes/fs/volume.py index b2e5d762af181..0d09333463e2e 100644 --- a/src/pybind/mgr/volumes/fs/volume.py +++ b/src/pybind/mgr/volumes/fs/volume.py @@ -232,12 +232,13 @@ class VolumeClient(CephfsClient["Module"]): mode = kwargs['mode'] isolate_nspace = kwargs['namespace_isolated'] earmark = kwargs['earmark'] or '' # if not set, default to empty string --> no earmark + normalization = kwargs['normalization'] oct_mode = octal_str_to_decimal_int(mode) try: create_subvol( - self.mgr, fs_handle, self.volspec, group, subvolname, size, isolate_nspace, pool, oct_mode, uid, gid, earmark) + self.mgr, fs_handle, self.volspec, group, subvolname, size, isolate_nspace, pool, oct_mode, uid, gid, earmark, normalization) except VolumeException as ve: # kick the purge threads for async removal -- note that this # assumes that the subvolume is moved to trashcan for cleanup on error. @@ -256,6 +257,7 @@ class VolumeClient(CephfsClient["Module"]): mode = kwargs['mode'] isolate_nspace = kwargs['namespace_isolated'] earmark = kwargs['earmark'] or '' # if not set, default to empty string --> no earmark + normalization = kwargs['normalization'] try: with open_volume(self, volname) as fs_handle: @@ -270,7 +272,8 @@ class VolumeClient(CephfsClient["Module"]): 'data_pool': pool, 'pool_namespace': subvolume.namespace if isolate_nspace else None, 'quota': size, - 'earmark': earmark + 'earmark': earmark, + 'normalization': normalization, } subvolume.set_attrs(subvolume.path, attrs) except VolumeException as ve: diff --git a/src/pybind/mgr/volumes/module.py b/src/pybind/mgr/volumes/module.py index 622aef8362e33..9281a925b6e99 100644 --- a/src/pybind/mgr/volumes/module.py +++ b/src/pybind/mgr/volumes/module.py @@ -144,7 +144,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule): 'name=gid,type=CephInt,req=false ' 'name=mode,type=CephString,req=false ' 'name=namespace_isolated,type=CephBool,req=false ' - 'name=earmark,type=CephString,req=false ', + 'name=earmark,type=CephString,req=false ' + 'name=normalization,type=CephChoices,strings=nfd|nfc|nfkd|nfkc,req=false ', 'desc': "Create a CephFS subvolume in a volume, and optionally, " "with a specific size (in bytes), a specific data pool layout, " "a specific mode, in a specific subvolume group and in separate " @@ -759,7 +760,8 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule): gid=cmd.get('gid', None), mode=cmd.get('mode', '755'), namespace_isolated=cmd.get('namespace_isolated', False), - earmark=cmd.get('earmark', None)) + earmark=cmd.get('earmark', None), + normalization=cmd.get('normalization', None)) @mgr_cmd_wrap def _cmd_fs_subvolume_rm(self, inbuf, cmd): -- 2.39.5