EARMARK_GET = 'earmark-get'
EARMARK_SET = 'earmark-set'
EARMARK_CLEAR = 'earmark-clear'
+ SNAPSHOT_VISIBILITY = 'snapshot-visibility'
class SubvolumeTemplate(object):
VERSION = None # type: int
f"subvolume={self.subvol_name} group={self.group_name} "
f"reason={me.args[1]}, errno:{-me.args[0]}, {os.strerror(-me.args[0])}")
raise VolumeException(-me.args[0], me.args[1])
+
+ def snapshot_visibility_set(self, value):
+ if value not in ("true", "false"):
+ raise VolumeException(-errno.EINVAL, "snapshot visibility value invalid")
+
+ subvol_root_path = os.path.dirname(self.path)
+ subvol_v2_path = self.path
+ snaps_visibility_vxattr = "ceph.dir.subvolume.snaps.visible"
+ subvolume_size = 0
+ try:
+ self.fs.setxattr(subvol_root_path, snaps_visibility_vxattr,
+ str(value).encode('utf-8'), 0)
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+
+ # in case of a sized subvolume, a new srnode will be assigned to the
+ # volumes/<group-name>/<subvolume-name>/<uuid>/ path when applying
+ # ceph.quota.max_bytes which would assign it with the default value
+ # of is_snapdir_visible flag and right now the child snaprealm
+ # changes are not being compiled and sent to the client by MDS, so until
+ # that gets addressed, as a quick fix apply the vxattr on subvol root
+ # and the uuid path. Once the child snaprealm fix is in place, apply
+ # the vxattr only to subvolume root.
+ try:
+ subvolume_size = self.fs.getxattr(
+ subvol_v2_path, "ceph.quota.max_bytes").decode('utf-8')
+ except cephfs.NoData:
+ # should be non-sized subvol v2 path
+ pass
+ if int(subvolume_size) > 0:
+ try:
+ self.fs.setxattr(subvol_v2_path, snaps_visibility_vxattr,
+ str(value).encode('utf-8'), 0)
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+
+ try:
+ subvol_v2_path_snapshot_visibility = self.fs.getxattr(subvol_v2_path,
+ snaps_visibility_vxattr).decode('utf-8')
+ if bool(subvol_v2_path_snapshot_visibility) != bool(value):
+ raise VolumeException(-errno.EINVAL, "could not set "
+ f"{snaps_visibility_vxattr} to {value} "
+ f"on subvolume v2 path {subvol_v2_path}")
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+
+ try:
+ return self.fs.getxattr(subvol_root_path,
+ snaps_visibility_vxattr).decode('utf-8')
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+
+ def snapshot_visibility_get(self):
+ subvol_parent_path = os.path.dirname(self.path)
+ try:
+ return self.fs.getxattr(subvol_parent_path,
+ "ceph.dir.subvolume.snaps.visible").decode('utf-8')
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
except VolumeException as ve:
ret = self.volume_exception_to_retval(ve)
return ret
+
+ def subvolume_snapshot_visibility_set(self, **kwargs):
+ ret = 0, "", ""
+ volname = kwargs['vol_name']
+ subvolname = kwargs['sub_name']
+ groupname = kwargs['group_name']
+ value = kwargs['value']
+
+ try:
+ with open_volume(self, volname) as fs_handle:
+ with open_group(fs_handle, self.volspec, groupname) as group:
+ with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname,
+ SubvolumeOpType.SNAPSHOT_VISIBILITY) as subvolume:
+ v = subvolume.snapshot_visibility_set(value)
+ ret = 0, v, ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
+
+ def subvolume_snapshot_visibility_get(self, **kwargs):
+ ret = 0, "", ""
+ volname = kwargs['vol_name']
+ subvolname = kwargs['sub_name']
+ groupname = kwargs['group_name']
+
+ try:
+ with open_volume(self, volname) as fs_handle:
+ with open_group(fs_handle, self.volspec, groupname) as group:
+ with open_subvol(self.mgr, fs_handle, self.volspec, group, subvolname,
+ SubvolumeOpType.SNAPSHOT_VISIBILITY) as subvolume:
+ v = subvolume.snapshot_visibility_get()
+ ret = 0, v, ""
+ except VolumeException as ve:
+ ret = self.volume_exception_to_retval(ve)
+ return ret
'desc': "Cancel an pending or ongoing clone operation.",
'perm': 'r'
},
+ {
+ 'cmd': 'fs subvolume snapshot_visibility set'
+ ' name=vol_name,type=CephString'
+ ' name=sub_name,type=CephString'
+ ' name=value,type=CephString,req=true'
+ ' name=group_name,type=CephString,req=false',
+ 'desc': "Set snapdir visibility for subvolume",
+ 'perm': 'rw'
+ },
+ {
+ 'cmd': 'fs subvolume snapshot_visibility get'
+ ' name=vol_name,type=CephString'
+ ' name=sub_name,type=CephString'
+ ' name=group_name,type=CephString,req=false',
+ 'desc': "Get snapdir visibility for subvolume",
+ 'perm': 'rw'
+ },
# volume ls [recursive]
# subvolume ls <volume>
# volume authorize/deauthorize
return self.vc.subvolume_info(vol_name=vol_name,
sub_name=subvol,
group_name=group_name)
+
+ @mgr_cmd_wrap
+ def _cmd_fs_subvolume_snapshot_visibility_set(self, inbuf, cmd):
+ return self.vc.subvolume_snapshot_visibility_set(vol_name=cmd['vol_name'],
+ sub_name=cmd['sub_name'],
+ value=cmd['value'],
+ group_name=cmd.get('group_name', None))
+
+ @mgr_cmd_wrap
+ def _cmd_fs_subvolume_snapshot_visibility_get(self, inbuf, cmd):
+ return self.vc.subvolume_snapshot_visibility_get(vol_name=cmd['vol_name'],
+ sub_name=cmd['sub_name'],
+ group_name=cmd.get('group_name', None))