Skip to content

Commit

Permalink
Merge pull request #12529 from SUSE/wip-18270-jewel
Browse files Browse the repository at this point in the history
jewel: rbd: add image id block name prefix APIs

Reviewed-by: Mykola Golub <mgolub@mirantis.com>
  • Loading branch information
smithfarm committed Jan 30, 2017
2 parents 18cb72c + aa8e57d commit 60bc353
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 45 deletions.
12 changes: 8 additions & 4 deletions src/include/rbd/librbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extern "C" {

#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)

Expand Down Expand Up @@ -86,9 +86,9 @@ typedef struct {
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 {
Expand Down Expand Up @@ -287,6 +287,10 @@ CEPH_RBD_API int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit);
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,
Expand Down
3 changes: 3 additions & 0 deletions src/include/rbd/librbd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ class CEPH_RBD_API Image
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);
Expand Down
56 changes: 56 additions & 0 deletions src/librbd/librbd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,28 @@ namespace librbd {
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)
{
Expand Down Expand Up @@ -2024,6 +2046,40 @@ extern "C" int rbd_get_overlap(rbd_image_t image, uint64_t *overlap)
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)
Expand Down
51 changes: 51 additions & 0 deletions src/pybind/rbd/rbd.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ cdef extern from "rbd/librbd.h" nogil:
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,
Expand Down Expand Up @@ -1126,6 +1129,54 @@ cdef class Image(object):
'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)
Expand Down
84 changes: 84 additions & 0 deletions src/test/librbd/test_librbd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,90 @@ TEST_F(TestLibRBD, CreateAndStatPP)
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;
Expand Down
9 changes: 1 addition & 8 deletions src/test/librbd/test_support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,10 @@ int create_image_pp(librbd::RBD &rbd, librados::IoCtx &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;
}

13 changes: 10 additions & 3 deletions src/test/pybind/test_rbd.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
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,
Expand Down Expand Up @@ -190,14 +190,14 @@ def test_create_defaults():
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:
Expand Down Expand Up @@ -315,6 +315,13 @@ def test_create_with_params(self):
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))
Expand Down
13 changes: 4 additions & 9 deletions src/tools/rbd/Utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -644,17 +644,12 @@ int snap_set(librbd::Image &image, const std::string &snap_name) {
}

std::string image_id(librbd::Image& image) {
librbd::image_info_t info;
int r = image.stat(info, sizeof(info));
std::string id;
int r = image.get_id(&id);
if (r < 0) {
return string();
return std::string();
}

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';

return string(prefix + strlen(RBD_DATA_PREFIX));
return id;
}

std::string mirror_image_state(librbd::mirror_image_state_t state) {
Expand Down
4 changes: 1 addition & 3 deletions src/tools/rbd/action/Info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ static int do_show_info(const char *imgname, librbd::Image& image,
}
}

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';
std::string prefix = image.get_block_name_prefix();

if (f) {
f->open_object_section("image");
Expand Down
14 changes: 5 additions & 9 deletions src/tools/rbd/action/Status.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ namespace po = boost::program_options;
static int do_show_status(librados::IoCtx &io_ctx, librbd::Image &image,
const char *imgname, Formatter *f)
{
librbd::image_info_t info;
uint8_t old_format;
int r;
std::string header_oid;
Expand All @@ -34,16 +33,13 @@ static int do_show_status(librados::IoCtx &io_ctx, librbd::Image &image,
header_oid = imgname;
header_oid += RBD_SUFFIX;
} else {
r = image.stat(info, sizeof(info));
if (r < 0)
std::string id;
r = image.get_id(&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';

header_oid = RBD_HEADER_PREFIX;
header_oid.append(prefix + strlen(RBD_DATA_PREFIX));
header_oid = RBD_HEADER_PREFIX + id;
}

r = io_ctx.list_watchers(header_oid, &watchers);
Expand Down

0 comments on commit 60bc353

Please sign in to comment.