char *group_snap_name;
} rbd_snap_group_namespace_t;
+typedef struct {
+ rbd_snap_namespace_type_t original_namespace_type;
+ char *original_name;
+} rbd_snap_trash_namespace_t;
+
typedef enum {
RBD_SNAP_MIRROR_STATE_PRIMARY,
RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED,
uint64_t snap_id,
char* original_name,
size_t max_length);
+CEPH_RBD_API int rbd_snap_get_trash_namespace2(
+ rbd_image_t image, uint64_t snap_id,
+ rbd_snap_trash_namespace_t *trash_snap, size_t trash_snap_size);
+CEPH_RBD_API int rbd_snap_trash_namespace_cleanup(
+ rbd_snap_trash_namespace_t *trash_snap, size_t trash_snap_size);
CEPH_RBD_API int rbd_snap_get_mirror_namespace(
rbd_image_t image, uint64_t snap_id,
rbd_snap_mirror_namespace_t *mirror_snap, size_t mirror_snap_size);
std::string group_snap_name;
} snap_group_namespace_t;
+ typedef struct {
+ snap_namespace_type_t original_namespace_type;
+ std::string original_name;
+ } snap_trash_namespace_t;
+
typedef rbd_snap_mirror_state_t snap_mirror_state_t;
typedef struct {
snap_group_namespace_t *group_namespace,
size_t snap_group_namespace_size);
int snap_get_trash_namespace(uint64_t snap_id, std::string* original_name);
+ int snap_get_trash_namespace2(uint64_t snap_id,
+ snap_trash_namespace_t *trash_namespace,
+ size_t snap_trash_namespace_size);
int snap_get_mirror_namespace(
uint64_t snap_id, snap_mirror_namespace_t *mirror_namespace,
size_t snap_mirror_namespace_size);
class GetTrashVisitor {
public:
- std::string* original_name;
+ snap_trash_namespace_t *trash_snap;
- explicit GetTrashVisitor(std::string* original_name)
- : original_name(original_name) {
+ explicit GetTrashVisitor(snap_trash_namespace_t *trash_snap)
+ : trash_snap(trash_snap) {
}
template <typename T>
inline int operator()(
const cls::rbd::TrashSnapshotNamespace& snap_namespace) {
- *original_name = snap_namespace.original_name;
+ trash_snap->original_namespace_type = static_cast<snap_namespace_type_t>(
+ snap_namespace.original_snapshot_namespace_type);
+ trash_snap->original_name = snap_namespace.original_name;
return 0;
}
};
template <typename I>
int Snapshot<I>::get_trash_namespace(I *ictx, uint64_t snap_id,
- std::string* original_name) {
+ snap_trash_namespace_t *trash_snap) {
int r = ictx->state->refresh_if_required();
if (r < 0) {
return r;
return -ENOENT;
}
- auto visitor = GetTrashVisitor(original_name);
+ auto visitor = GetTrashVisitor(trash_snap);
r = snap_info->snap_namespace.visit(visitor);
if (r < 0) {
return r;
snap_group_namespace_t *group_snap);
static int get_trash_namespace(ImageCtxT *ictx, uint64_t snap_id,
- std::string *original_name);
+ snap_trash_namespace_t *trash_snap);
static int get_mirror_namespace(
ImageCtxT *ictx, uint64_t snap_id,
int Image::snap_get_trash_namespace(uint64_t snap_id,
std::string* original_name) {
ImageCtx *ictx = (ImageCtx *)ctx;
+
+ snap_trash_namespace_t trash_snap;
+ int r = librbd::api::Snapshot<>::get_trash_namespace(ictx, snap_id,
+ &trash_snap);
+ if (r < 0) {
+ return r;
+ }
+
+ *original_name = trash_snap.original_name;
+ return 0;
+ }
+
+ int Image::snap_get_trash_namespace2(
+ uint64_t snap_id, snap_trash_namespace_t *trash_snap,
+ size_t trash_snap_size) {
+ ImageCtx *ictx = (ImageCtx *)ctx;
+
+ if (trash_snap_size != sizeof(snap_trash_namespace_t)) {
+ return -ERANGE;
+ }
+
return librbd::api::Snapshot<>::get_trash_namespace(ictx, snap_id,
- original_name);
+ trash_snap);
}
int Image::snap_get_mirror_namespace(
size_t max_length) {
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
- std::string cpp_original_name;
+ librbd::snap_trash_namespace_t trash_namespace;
int r = librbd::api::Snapshot<>::get_trash_namespace(ictx, snap_id,
- &cpp_original_name);
+ &trash_namespace);
if (r < 0) {
return r;
}
- if (cpp_original_name.length() >= max_length) {
+ if (trash_namespace.original_name.length() >= max_length) {
+ return -ERANGE;
+ }
+
+ strcpy(original_name, trash_namespace.original_name.c_str());
+ return 0;
+}
+
+extern "C" int rbd_snap_get_trash_namespace2(
+ rbd_image_t image, uint64_t snap_id,
+ rbd_snap_trash_namespace_t *trash_snap,
+ size_t trash_snap_size) {
+ librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+
+ if (trash_snap_size != sizeof(rbd_snap_trash_namespace_t)) {
+ return -ERANGE;
+ }
+
+ librbd::snap_trash_namespace_t trash_namespace;
+ int r = librbd::api::Snapshot<>::get_trash_namespace(ictx, snap_id,
+ &trash_namespace);
+ if (r < 0) {
+ return r;
+ }
+
+ trash_snap->original_namespace_type = trash_namespace.original_namespace_type;
+ trash_snap->original_name = strdup(trash_namespace.original_name.c_str());
+ return 0;
+}
+
+extern "C" int rbd_snap_trash_namespace_cleanup(
+ rbd_snap_trash_namespace_t *trash_snap, size_t trash_snap_size) {
+ if (trash_snap_size != sizeof(rbd_snap_trash_namespace_t)) {
return -ERANGE;
}
- strcpy(original_name, cpp_original_name.c_str());
+ free(trash_snap->original_name);
return 0;
}
char *group_name
char *group_snap_name
+ ctypedef struct rbd_snap_trash_namespace_t:
+ rbd_snap_namespace_type_t original_namespace_type;
+ char *original_name;
+
ctypedef enum rbd_snap_mirror_state_t:
_RBD_SNAP_MIRROR_STATE_PRIMARY "RBD_SNAP_MIRROR_STATE_PRIMARY"
_RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED "RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED"
size_t snap_group_namespace_size)
void rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_spec,
size_t snap_group_namespace_size)
- int rbd_snap_get_trash_namespace(rbd_image_t image, uint64_t snap_id,
- char *original_name, size_t max_length)
+ int rbd_snap_get_trash_namespace2(rbd_image_t image, uint64_t snap_id,
+ rbd_snap_trash_namespace_t *trash_snap,
+ size_t trash_snap_size)
+ void rbd_snap_trash_namespace_cleanup(rbd_snap_trash_namespace_t *trash_snap,
+ size_t trash_snap_size)
int rbd_snap_get_mirror_namespace(
rbd_image_t image, uint64_t snap_id,
rbd_snap_mirror_namespace_t *mirror_ns,
char *group_name
char *group_snap_name
+ ctypedef struct rbd_snap_trash_namespace_t:
+ rbd_snap_namespace_type_t original_namespace_type;
+ char *original_name;
+
ctypedef enum rbd_snap_mirror_state_t:
_RBD_SNAP_MIRROR_STATE_PRIMARY "RBD_SNAP_MIRROR_STATE_PRIMARY"
_RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED "RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED"
void rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_spec,
size_t snap_group_namespace_size):
pass
- int rbd_snap_get_trash_namespace(rbd_image_t image, uint64_t snap_id,
- char *original_name, size_t max_length):
+ int rbd_snap_get_trash_namespace2(rbd_image_t image, uint64_t snap_id,
+ rbd_snap_trash_namespace_t *trash_snap,
+ size_t trash_snap_size):
+ pass
+ void rbd_snap_trash_namespace_cleanup(rbd_snap_trash_namespace_t *trash_snap,
+ size_t trash_snap_size):
pass
int rbd_snap_get_mirror_namespace(
rbd_image_t image, uint64_t snap_id,
:type key: int
:returns: dict - contains the following keys:
+ * ``original_namespace_type`` (int) - original snap namespace type
+
* ``original_name`` (str) - original snap name
"""
cdef:
+ rbd_snap_trash_namespace_t trash_snap
uint64_t _snap_id = snap_id
- size_t _size = 512
- char *_name = NULL
- try:
- while True:
- _name = <char*>realloc_chk(_name, _size);
- with nogil:
- ret = rbd_snap_get_trash_namespace(self.image, _snap_id,
- _name, _size)
- if ret >= 0:
- break
- elif ret != -errno.ERANGE:
- raise make_ex(ret, 'error getting snapshot trash '
- 'namespace image: %s, snap_id: %d' % (self.name, snap_id))
- return {
- 'original_name' : decode_cstr(_name)
- }
- finally:
- free(_name)
+ with nogil:
+ ret = rbd_snap_get_trash_namespace2(self.image, _snap_id,
+ &trash_snap, sizeof(trash_snap))
+ if ret != 0:
+ raise make_ex(ret, 'error getting snapshot trash '
+ 'namespace for image: %s, snap_id: %d' %
+ (self.name, snap_id))
+ result = {
+ 'original_namespace_type' : trash_snap.original_namespace_type,
+ 'original_name' : decode_cstr(trash_snap.original_name)
+ }
+ rbd_snap_trash_namespace_cleanup(&trash_snap, sizeof(trash_snap))
+ return result
@requires_not_closed
def snap_get_mirror_namespace(self, snap_id):
RBD_MIRROR_IMAGE_MODE_JOURNAL, RBD_MIRROR_IMAGE_MODE_SNAPSHOT,
RBD_LOCK_MODE_EXCLUSIVE, RBD_OPERATION_FEATURE_GROUP,
RBD_OPERATION_FEATURE_CLONE_CHILD,
+ RBD_SNAP_NAMESPACE_TYPE_USER,
RBD_SNAP_NAMESPACE_TYPE_GROUP,
RBD_SNAP_NAMESPACE_TYPE_TRASH,
RBD_SNAP_NAMESPACE_TYPE_MIRROR,
self.image.remove_snap('snap2')
trash_snap = self.image.snap_get_trash_namespace(snap_id)
assert trash_snap == {
+ 'original_namespace_type' : RBD_SNAP_NAMESPACE_TYPE_USER,
'original_name' : 'snap2'
}
clone_name3 = get_temp_image_name()
snaps = [s for s in self.image.list_snaps() if s['name'] != 'snap1']
eq([RBD_SNAP_NAMESPACE_TYPE_TRASH], [s['namespace'] for s in snaps])
- eq([{'original_name' : 'snap2'}], [s['trash'] for s in snaps])
+ trash_snap = {
+ 'original_namespace_type' : RBD_SNAP_NAMESPACE_TYPE_USER,
+ 'original_name' : 'snap2'
+ }
+ eq([trash_snap], [s['trash'] for s in snaps])
self.rbd.remove(ioctx, clone_name)
eq([], [s for s in self.image.list_snaps() if s['name'] != 'snap1'])
trash_image_snap_name = image_snaps[0]['name']
assert image_snaps[0]['id'] == image_snap_id
assert image_snaps[0]['trash'] == {
+ 'original_namespace_type' : RBD_SNAP_NAMESPACE_TYPE_GROUP,
'original_name' : image_snap_name
}
assert trash_image_snap_name != image_snap_name