-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
char *parent_name, size_t pnamelen,
char *parent_snapname,
size_t psnapnamelen);
+CEPH_RBD_API int rbd_get_parent_info2(rbd_image_t image,
+ char *parent_poolname,
+ size_t ppoolnamelen,
+ char *parent_name, size_t pnamelen,
+ char *parent_id, size_t pidlen,
+ char *parent_snapname,
+ size_t psnapnamelen);
CEPH_RBD_API int rbd_get_flags(rbd_image_t image, uint64_t *flags);
CEPH_RBD_API int rbd_set_image_notification(rbd_image_t image, int fd, int type);
std::string get_block_name_prefix();
int64_t get_data_pool_id();
int parent_info(std::string *parent_poolname, std::string *parent_name,
- std::string *parent_snapname);
+ std::string *parent_snapname);
+ int parent_info2(std::string *parent_poolname, std::string *parent_name,
+ std::string *parent_id, std::string *parent_snapname);
int old_format(uint8_t *old);
int size(uint64_t *size);
int get_group(group_spec_t *group_spec);
}
int get_parent_info(ImageCtx *ictx, string *parent_pool_name,
- string *parent_name, string *parent_snap_name)
+ string *parent_name, string *parent_id,
+ string *parent_snap_name)
{
int r = ictx->state->refresh_if_required();
if (r < 0)
RWLock::RLocker snap_locker(ictx->parent->snap_lock);
*parent_name = ictx->parent->name;
}
+ if (parent_id) {
+ *parent_id = ictx->parent->id;
+ }
return 0;
}
int get_features(ImageCtx *ictx, uint64_t *features);
int get_overlap(ImageCtx *ictx, uint64_t *overlap);
int get_parent_info(ImageCtx *ictx, std::string *parent_pool_name,
- std::string *parent_name, std::string *parent_snap_name);
+ std::string *parent_name, std::string *parent_id,
+ std::string *parent_snap_name);
int get_flags(ImageCtx *ictx, uint64_t *flags);
int set_image_notification(ImageCtx *ictx, int fd, int type);
int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner);
int Image::parent_info(string *parent_pool_name, string *parent_name,
string *parent_snap_name)
+ {
+ return parent_info2(parent_pool_name, parent_name, nullptr,
+ parent_snap_name);
+ }
+
+ int Image::parent_info2(string *parent_pool_name, string *parent_name,
+ string *parent_id, string *parent_snap_name)
{
ImageCtx *ictx = (ImageCtx *)ctx;
- tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only);
+ tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(),
+ ictx->snap_name.c_str(), ictx->read_only);
int r = librbd::get_parent_info(ictx, parent_pool_name, parent_name,
- parent_snap_name);
- tracepoint(librbd, get_parent_info_exit, r, parent_pool_name ? parent_pool_name->c_str() : NULL, parent_name ? parent_name->c_str() : NULL, parent_snap_name ? parent_snap_name->c_str() : NULL);
+ parent_id, parent_snap_name);
+ tracepoint(librbd, get_parent_info_exit, r,
+ parent_pool_name ? parent_pool_name->c_str() : NULL,
+ parent_name ? parent_name->c_str() : NULL,
+ parent_id ? parent_id->c_str() : NULL,
+ parent_snap_name ? parent_snap_name->c_str() : NULL);
return r;
}
}
extern "C" int rbd_get_parent_info(rbd_image_t image,
- char *parent_pool_name, size_t ppool_namelen, char *parent_name,
- size_t pnamelen, char *parent_snap_name, size_t psnap_namelen)
+ char *parent_pool_name, size_t ppool_namelen,
+ char *parent_name, size_t pnamelen,
+ char *parent_snap_name, size_t psnap_namelen)
+{
+ return rbd_get_parent_info2(image, parent_pool_name, ppool_namelen,
+ parent_name, pnamelen, nullptr, 0,
+ parent_snap_name, psnap_namelen);
+}
+
+extern "C" int rbd_get_parent_info2(rbd_image_t image,
+ char *parent_pool_name,
+ size_t ppool_namelen,
+ char *parent_name, size_t pnamelen,
+ char *parent_id, size_t pidlen,
+ char *parent_snap_name,
+ size_t psnap_namelen)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
- tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only);
- string p_pool_name, p_name, p_snap_name;
+ tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(),
+ ictx->snap_name.c_str(), ictx->read_only);
+ string p_pool_name, p_name, p_id, p_snap_name;
- int r = librbd::get_parent_info(ictx, &p_pool_name, &p_name, &p_snap_name);
+ int r = librbd::get_parent_info(ictx, &p_pool_name, &p_name, &p_id,
+ &p_snap_name);
if (r < 0) {
- tracepoint(librbd, get_parent_info_exit, r, NULL, NULL, NULL);
+ tracepoint(librbd, get_parent_info_exit, r, NULL, NULL, NULL, NULL);
return r;
}
if (parent_pool_name) {
if (p_pool_name.length() + 1 > ppool_namelen) {
- tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL);
+ tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
return -ERANGE;
}
}
if (parent_name) {
if (p_name.length() + 1 > pnamelen) {
- tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL);
+ tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
return -ERANGE;
}
strcpy(parent_name, p_name.c_str());
}
+ if (parent_id) {
+ if (p_id.length() + 1 > pidlen) {
+ tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
+ return -ERANGE;
+ }
+
+ strcpy(parent_id, p_id.c_str());
+ }
if (parent_snap_name) {
if (p_snap_name.length() + 1 > psnap_namelen) {
- tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL);
+ tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
return -ERANGE;
}
strcpy(parent_snap_name, p_snap_name.c_str());
}
- tracepoint(librbd, get_parent_info_exit, 0, parent_pool_name, parent_name, parent_snap_name);
+ tracepoint(librbd, get_parent_info_exit, 0, parent_pool_name, parent_name,
+ parent_id, parent_snap_name);
return 0;
}
int rbd_get_id(rbd_image_t image, char *id, size_t id_len)
int rbd_get_block_name_prefix(rbd_image_t image, char *prefix,
size_t prefix_len)
- int rbd_get_parent_info(rbd_image_t image,
- char *parent_poolname, size_t ppoolnamelen,
- char *parent_name, size_t pnamelen,
- char *parent_snapname, size_t psnapnamelen)
+ int rbd_get_parent_info2(rbd_image_t image,
+ char *parent_poolname, size_t ppoolnamelen,
+ char *parent_name, size_t pnamelen,
+ char *parent_id, size_t pidlen,
+ char *parent_snapname, size_t psnapnamelen)
int rbd_get_flags(rbd_image_t image, uint64_t *flags)
ssize_t rbd_read2(rbd_image_t image, uint64_t ofs, size_t len,
char *buf, int op_flags)
name = <char *>realloc_chk(name, size)
snapname = <char *>realloc_chk(snapname, size)
with nogil:
- ret = rbd_get_parent_info(self.image, pool, size, name,
- size, snapname, size)
+ ret = rbd_get_parent_info2(self.image, pool, size, name,
+ size, NULL, 0, snapname, size)
if ret == -errno.ERANGE:
size *= 2
free(name)
free(snapname)
+ def parent_id(self):
+ """
+ Get image id of a cloned image's parent (if any)
+
+ :returns: str - the parent id
+ :raises: :class:`ImageNotFound` if the image doesn't have a parent
+ """
+ cdef:
+ int ret = -errno.ERANGE
+ size_t size = 32
+ char *parent_id = NULL
+ try:
+ while ret == -errno.ERANGE and size <= 4096:
+ parent_id = <char *>realloc_chk(parent_id, size)
+ with nogil:
+ ret = rbd_get_parent_info2(self.image, NULL, 0, NULL, 0,
+ parent_id, size, NULL, 0)
+ if ret == -errno.ERANGE:
+ size *= 2
+
+ if ret != 0:
+ raise make_ex(ret, 'error getting parent id for image %s' % (self.name,))
+ return decode_cstr(parent_id)
+ finally:
+ free(parent_id)
+
def old_format(self):
"""
Find out whether the image uses the old RBD format.
eq(pool, pool_name)
eq(image, image_name)
eq(snap, 'snap1')
+ eq(self.image.id(), self.clone.parent_id())
# create a new pool...
pool_name2 = get_temp_pool_name()
eq(pool, pool_name)
eq(image, image_name)
eq(snap, 'snap1')
+ eq(self.image.id(), self.other_clone.parent_id())
# can't unprotect snap with children
assert_raises(ImageBusy, self.image.unprotect_snap, 'snap1')
clone.flatten()
assert_raises(ImageNotFound, clone.parent_info)
assert_raises(ImageNotFound, clone2.parent_info)
+ assert_raises(ImageNotFound, clone.parent_id)
+ assert_raises(ImageNotFound, clone2.parent_id)
after_flatten = clone.read(IMG_SIZE // 2, 256)
eq(data, after_flatten)
after_flatten = clone2.read(IMG_SIZE // 2, 256)
image1.write(data, 0)
image2.flatten()
assert_raises(ImageNotFound, image1.parent_info)
+ assert_raises(ImageNotFound, image1.parent_id)
parent = True
for x in range(30):
try:
int, retval,
const char*, parent_pool_name,
const char*, parent_name,
+ const char*, parent_id,
const char*, parent_snap_name),
TP_FIELDS(
ctf_integer(int, retval, retval)
ceph_ctf_string(parent_pool_name, parent_pool_name)
ceph_ctf_string(parent_name, parent_name)
+ ceph_ctf_string(parent_id, parent_id)
ceph_ctf_string(parent_snap_name, parent_snap_name)
)
)