#define LIBRBD_VER_MAJOR 0
#define LIBRBD_VER_MINOR 1
-#define LIBRBD_VER_EXTRA 10
+#define LIBRBD_VER_EXTRA 11
#define LIBRBD_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
uint64_t obj_size;
uint64_t num_objs;
int order;
- char block_name_prefix[RBD_MAX_BLOCK_NAME_SIZE];
- int64_t parent_pool; /* deprecated */
- char parent_name[RBD_MAX_IMAGE_NAME_SIZE]; /* deprecated */
+ char block_name_prefix[RBD_MAX_BLOCK_NAME_SIZE]; /* deprecated */
+ int64_t parent_pool; /* deprecated */
+ char parent_name[RBD_MAX_IMAGE_NAME_SIZE]; /* deprecated */
} rbd_image_info_t;
typedef enum {
CEPH_RBD_API int rbd_get_stripe_count(rbd_image_t image,
uint64_t *stripe_count);
CEPH_RBD_API int rbd_get_overlap(rbd_image_t image, uint64_t *overlap);
+CEPH_RBD_API int rbd_get_id(rbd_image_t image, char *id, size_t id_len);
+CEPH_RBD_API int rbd_get_block_name_prefix(rbd_image_t image,
+ char *prefix, size_t prefix_len);
+CEPH_RBD_API int64_t rbd_get_data_pool_id(rbd_image_t image);
CEPH_RBD_API int rbd_get_parent_info(rbd_image_t image,
char *parent_poolname, size_t ppoolnamelen,
char *parent_name, size_t pnamelen,
int resize(uint64_t size);
int resize_with_progress(uint64_t size, ProgressContext& pctx);
int stat(image_info_t &info, size_t infosize);
+ int get_id(std::string *id);
+ 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);
int old_format(uint8_t *old);
return r;
}
+ int Image::get_id(std::string *id)
+ {
+ ImageCtx *ictx = reinterpret_cast<ImageCtx *>(ctx);
+ if (ictx->old_format) {
+ return -EINVAL;
+ }
+ *id = ictx->id;
+ return 0;
+ }
+
+ std::string Image::get_block_name_prefix()
+ {
+ ImageCtx *ictx = reinterpret_cast<ImageCtx *>(ctx);
+ return ictx->object_prefix;
+ }
+
+ int64_t Image::get_data_pool_id()
+ {
+ ImageCtx *ictx = reinterpret_cast<ImageCtx *>(ctx);
+ return ictx->data_ctx.get_id();
+ }
+
int Image::parent_info(string *parent_pool_name, string *parent_name,
string *parent_snap_name)
{
return r;
}
+extern "C" int rbd_get_id(rbd_image_t image, char *id, size_t id_len)
+{
+ librbd::ImageCtx *ictx = reinterpret_cast<librbd::ImageCtx *>(image);
+ if (ictx->old_format) {
+ return -EINVAL;
+ }
+ if (ictx->id.size() >= id_len) {
+ return -ERANGE;
+ }
+
+ strncpy(id, ictx->id.c_str(), id_len - 1);
+ id[id_len - 1] = '\0';
+ return 0;
+}
+
+extern "C" int rbd_get_block_name_prefix(rbd_image_t image, char *prefix,
+ size_t prefix_len)
+{
+ librbd::ImageCtx *ictx = reinterpret_cast<librbd::ImageCtx *>(image);
+ if (ictx->object_prefix.size() >= prefix_len) {
+ return -ERANGE;
+ }
+
+ strncpy(prefix, ictx->object_prefix.c_str(), prefix_len - 1);
+ prefix[prefix_len - 1] = '\0';
+ return 0;
+}
+
+extern "C" int64_t rbd_get_data_pool_id(rbd_image_t image)
+{
+ librbd::ImageCtx *ictx = reinterpret_cast<librbd::ImageCtx *>(image);
+ return ictx->data_ctx.get_id();
+}
+
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)
int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit)
int rbd_get_stripe_count(rbd_image_t image, uint64_t *stripe_count)
int rbd_get_overlap(rbd_image_t image, uint64_t *overlap)
+ 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,
'parent_name' : info.parent_name
}
+ def id(self):
+ """
+ Get the RBD v2 internal image id
+
+ :returns: str - image id
+ """
+ cdef:
+ int ret = -errno.ERANGE
+ size_t size = 32
+ char *image_id = NULL
+ try:
+ while ret == -errno.ERANGE and size <= 4096:
+ image_id = <char *>realloc_chk(image_id, size)
+ with nogil:
+ ret = rbd_get_id(self.image, image_id, size)
+ if ret == -errno.ERANGE:
+ size *= 2
+
+ if ret != 0:
+ raise make_ex(ret, 'error getting id for image %s' % (self.name,))
+ return decode_cstr(image_id)
+ finally:
+ free(image_id)
+
+ def block_name_prefix(self):
+ """
+ Get the RBD block name prefix
+
+ :returns: str - block name prefix
+ """
+ cdef:
+ int ret = -errno.ERANGE
+ size_t size = 32
+ char *prefix = NULL
+ try:
+ while ret == -errno.ERANGE and size <= 4096:
+ prefix = <char *>realloc_chk(prefix, size)
+ with nogil:
+ ret = rbd_get_block_name_prefix(self.image, prefix, size)
+ if ret == -errno.ERANGE:
+ size *= 2
+
+ if ret != 0:
+ raise make_ex(ret, 'error getting block name prefix for image %s' % (self.name,))
+ return decode_cstr(prefix)
+ finally:
+ free(prefix)
+
def parent_info(self):
"""
Get information about a cloned image's parent (if any)
ioctx.close();
}
+TEST_F(TestLibRBD, GetId)
+{
+ rados_ioctx_t ioctx;
+ ASSERT_EQ(0, rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx));
+
+ rbd_image_t image;
+ int order = 0;
+ std::string name = get_temp_image_name();
+
+ ASSERT_EQ(0, create_image(ioctx, name.c_str(), 0, &order));
+ ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL));
+
+ char id[4096];
+ if (!is_feature_enabled(0)) {
+ // V1 image
+ ASSERT_EQ(-EINVAL, rbd_get_id(image, id, sizeof(id)));
+ } else {
+ ASSERT_EQ(-ERANGE, rbd_get_id(image, id, 0));
+ ASSERT_EQ(0, rbd_get_id(image, id, sizeof(id)));
+ ASSERT_LT(0U, strlen(id));
+ }
+
+ ASSERT_EQ(0, rbd_close(image));
+ rados_ioctx_destroy(ioctx);
+}
+
+TEST_F(TestLibRBD, GetIdPP)
+{
+ librados::IoCtx ioctx;
+ ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+ librbd::RBD rbd;
+ librbd::Image image;
+ int order = 0;
+ std::string name = get_temp_image_name();
+
+ std::string id;
+ ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), 0, &order));
+ ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), NULL));
+ if (!is_feature_enabled(0)) {
+ // V1 image
+ ASSERT_EQ(-EINVAL, image.get_id(&id));
+ } else {
+ ASSERT_EQ(0, image.get_id(&id));
+ ASSERT_LT(0U, id.size());
+ }
+}
+
+TEST_F(TestLibRBD, GetBlockNamePrefix)
+{
+ rados_ioctx_t ioctx;
+ ASSERT_EQ(0, rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx));
+
+ rbd_image_t image;
+ int order = 0;
+ std::string name = get_temp_image_name();
+
+ ASSERT_EQ(0, create_image(ioctx, name.c_str(), 0, &order));
+ ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL));
+
+ char prefix[4096];
+ ASSERT_EQ(-ERANGE, rbd_get_block_name_prefix(image, prefix, 0));
+ ASSERT_EQ(0, rbd_get_block_name_prefix(image, prefix, sizeof(prefix)));
+ ASSERT_LT(0U, strlen(prefix));
+
+ ASSERT_EQ(0, rbd_close(image));
+ rados_ioctx_destroy(ioctx);
+}
+
+TEST_F(TestLibRBD, GetBlockNamePrefixPP)
+{
+ librados::IoCtx ioctx;
+ ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+ librbd::RBD rbd;
+ librbd::Image image;
+ int order = 0;
+ std::string name = get_temp_image_name();
+
+ ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), 0, &order));
+ ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), NULL));
+ ASSERT_LT(0U, image.get_block_name_prefix().size());
+}
+
TEST_F(TestLibRBD, OpenAio)
{
rados_ioctx_t ioctx;
int get_image_id(librbd::Image &image, std::string *image_id)
{
- librbd::image_info_t info;
- int r = image.stat(info, sizeof(info));
+ int r = image.get_id(image_id);
if (r < 0) {
return r;
}
-
- char prefix[RBD_MAX_BLOCK_NAME_SIZE + 1];
- strncpy(prefix, info.block_name_prefix, RBD_MAX_BLOCK_NAME_SIZE);
- prefix[RBD_MAX_BLOCK_NAME_SIZE] = '\0';
-
- *image_id = std::string(prefix + strlen(RBD_DATA_PREFIX));
return 0;
}
import time
from nose import with_setup, SkipTest
-from nose.tools import eq_ as eq, assert_raises
+from nose.tools import eq_ as eq, assert_raises, assert_not_equal
from rados import (Rados,
LIBRADOS_OP_FLAG_FADVISE_DONTNEED,
LIBRADOS_OP_FLAG_FADVISE_NOCACHE,
check_default_params(2, 20, RBD_FEATURE_STRIPINGV2, 1, 1 << 16)
check_default_params(2, 20, RBD_FEATURE_STRIPINGV2, 10, 1 << 20)
check_default_params(2, 20, RBD_FEATURE_STRIPINGV2, 10, 1 << 16)
- check_default_params(2, 20, RBD_FEATURE_STRIPINGV2, 0, 0)
+ check_default_params(2, 20, 0, 0, 0)
# make sure invalid combinations of stripe unit and order are still invalid
check_default_params(2, 22, RBD_FEATURE_STRIPINGV2, 10, 1 << 50, exception=InvalidArgument)
check_default_params(2, 22, RBD_FEATURE_STRIPINGV2, 10, 100, exception=InvalidArgument)
check_default_params(2, 22, RBD_FEATURE_STRIPINGV2, 0, 1, exception=InvalidArgument)
check_default_params(2, 22, RBD_FEATURE_STRIPINGV2, 1, 0, exception=InvalidArgument)
# 0 stripe unit and count are still ignored
- check_default_params(2, 22, RBD_FEATURE_STRIPINGV2, 0, 0)
+ check_default_params(2, 22, 0, 0, 0)
def test_context_manager():
with Rados(conffile='') as cluster:
image.close()
RBD().remove(ioctx, image_name)
+ @require_new_format()
+ def test_id(self):
+ assert_not_equal(b'', self.image.id())
+
+ def test_block_name_prefix(self):
+ assert_not_equal(b'', self.image.block_name_prefix())
+
def test_invalidate_cache(self):
self.image.write(b'abc', 0)
eq(b'abc', self.image.read(0, 3))