def features(self):
return [SubvolumeFeatures.FEATURE_SNAPSHOT_CLONE.value, SubvolumeFeatures.FEATURE_SNAPSHOT_AUTOPROTECT.value]
+ def mark_subvolume(self):
+ # set subvolume attr, on subvolume root, marking it as a CephFS subvolume
+ # subvolume root is where snapshots would be taken, and hence is the <uuid> dir for v1 subvolumes
+ xattr_val = 1
+ try:
+ self.fs.setxattr(self.path, 'ceph.dir.subvolume', str(xattr_val).encode('utf-8'), os.XATTR_CREATE)
+ except cephfs.ObjectExists:
+ return
+ except cephfs.InvalidValue as e:
+ raise VolumeException(-errno.EINVAL, "invalid value specified for ceph.dir.subvolume: '{0}'".format(xattr_val))
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+
def snapshot_base_path(self):
""" Base path for all snapshots """
return os.path.join(self.path, self.vol_spec.snapshot_dir_prefix.encode('utf-8'))
try:
# create directory and set attributes
self.fs.mkdirs(subvol_path, mode)
+ self.mark_subvolume()
attrs = {
'uid': uid,
'gid': gid,
# create directory and set attributes
self.fs.mkdirs(subvol_path, attrs.get("mode"))
+ self.mark_subvolume()
self.set_attrs(subvol_path, attrs)
# persist subvolume metadata and clone source
subvol_path = self.path
log.debug("refreshed metadata, checking subvolume path '{0}'".format(subvol_path))
st = self.fs.stat(subvol_path)
+ # unconditionally mark as subvolume, to handle pre-existing subvolumes without the mark
+ self.mark_subvolume()
self.uid = int(st.st_uid)
self.gid = int(st.st_gid)
else:
raise VolumeException(-e.args[0], e.args[1])
+ def mark_subvolume(self):
+ # set subvolume attr, on subvolume root, marking it as a CephFS subvolume
+ # subvolume root is where snapshots would be taken, and hence is the base_path for v2 subvolumes
+ xattr_val = 1
+ try:
+ self.fs.setxattr(self.base_path, 'ceph.dir.subvolume', str(xattr_val).encode('utf-8'), os.XATTR_CREATE)
+ except cephfs.ObjectExists:
+ return
+ except cephfs.InvalidValue as e:
+ raise VolumeException(-errno.EINVAL, "invalid value specified for ceph.dir.subvolume: '{0}'".format(xattr_val))
+ except cephfs.Error as e:
+ raise VolumeException(-e.args[0], e.args[1])
+
@staticmethod
def is_valid_uuid(uuid_str):
try:
subvol_path = os.path.join(self.base_path, str(uuid.uuid4()).encode('utf-8'))
try:
self.fs.mkdirs(subvol_path, mode)
+ self.mark_subvolume()
attrs = {
'uid': uid,
'gid': gid,
# create directory and set attributes
self.fs.mkdirs(subvol_path, attrs.get("mode"))
+ self.mark_subvolume()
self.set_attrs(subvol_path, attrs)
# persist subvolume metadata and clone source
op_type.value, self.subvolname))
try:
self.metadata_mgr.refresh()
+ # unconditionally mark as subvolume, to handle pre-existing subvolumes without the mark
+ self.mark_subvolume()
etype = self.subvol_type
if op_type not in self.allowed_ops_by_type(etype):