Merge pull request #31188 from zy751713126/rbd_features

librbd: features converting bitmask and string API

Reviewed-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2019-11-08 07:35:05 -05:00 committed by GitHub
commit 97db9473fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 0 deletions

View File

@ -627,6 +627,9 @@ CEPH_RBD_API int rbd_aio_open_read_only(rados_ioctx_t io, const char *name,
CEPH_RBD_API int rbd_aio_open_by_id_read_only(rados_ioctx_t io, const char *id,
rbd_image_t *image, const char *snap_name,
rbd_completion_t c);
CEPH_RBD_API int rbd_features_to_string(uint64_t features, char *str_features,
size_t *size);
CEPH_RBD_API int rbd_features_from_string(const char *str_features, uint64_t *features);
CEPH_RBD_API int rbd_close(rbd_image_t image);
CEPH_RBD_API int rbd_aio_close(rbd_image_t image, rbd_completion_t c);
CEPH_RBD_API int rbd_resize(rbd_image_t image, uint64_t size);

View File

@ -240,6 +240,8 @@ public:
const char *snapname, RBD::AioCompletion *c);
int aio_open_by_id_read_only(IoCtx& io_ctx, Image& image, const char *id,
const char *snapname, RBD::AioCompletion *c);
int features_to_string(uint64_t features, std::string *str_features);
int features_from_string(const std::string str_features, uint64_t *features);
int list(IoCtx& io_ctx, std::vector<std::string>& names)
CEPH_RBD_DEPRECATED;

View File

@ -23,6 +23,7 @@
#include "cls/rbd/cls_rbd_client.h"
#include "cls/rbd/cls_rbd_types.h"
#include "librbd/Features.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/internal.h"
@ -621,6 +622,28 @@ namespace librbd {
return 0;
}
int RBD::features_to_string(uint64_t features, std::string *str_features)
{
std::stringstream err;
*str_features = librbd::rbd_features_to_string(features, &err);
if (!err.str().empty()) {
return -EINVAL;
}
return 0;
}
int RBD::features_from_string(const std::string str_features, uint64_t *features)
{
std::stringstream err;
*features = librbd::rbd_features_from_string(str_features, &err);
if (!err.str().empty()) {
return -EINVAL;
}
return 0;
}
int RBD::create(IoCtx& io_ctx, const char *name, uint64_t size, int *order)
{
TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
@ -4517,6 +4540,35 @@ extern "C" int rbd_aio_open_by_id_read_only(rados_ioctx_t p, const char *id,
return 0;
}
extern "C" int rbd_features_to_string(uint64_t features, char *str_features, size_t *size)
{
std::stringstream err;
std::string get_str_features = librbd::rbd_features_to_string(features, &err);
if (!err.str().empty()) {
return -EINVAL;
}
uint64_t expected_size = get_str_features.size();
if (*size <= expected_size) {
*size = expected_size + 1;
return -ERANGE;
}
strncpy(str_features, get_str_features.c_str(), expected_size);
str_features[expected_size] = '\0';
*size = expected_size + 1;
return 0;
}
extern "C" int rbd_features_from_string(const char *str_features, uint64_t *features)
{
std::stringstream err;
*features = librbd::rbd_features_from_string(str_features, &err);
if (!err.str().empty()) {
return -EINVAL;
}
return 0;
}
extern "C" int rbd_close(rbd_image_t image)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;

View File

@ -427,6 +427,8 @@ cdef extern from "rbd/librbd.h" nogil:
rbd_image_t *image, const char *snap_name)
int rbd_open_by_id_read_only(rados_ioctx_t io, const char *image_id,
rbd_image_t *image, const char *snap_name)
int rbd_features_to_string(uint64_t features, char *str_features, size_t *size)
int rbd_features_from_string(const char *str_features, uint64_t *features)
int rbd_close(rbd_image_t image)
int rbd_resize2(rbd_image_t image, uint64_t size, bint allow_shrink,
librbd_progress_fn_t cb, void *cbdata)
@ -2517,6 +2519,52 @@ class RBD(object):
finally:
rbd_pool_stats_destroy(_stats)
def features_to_string(self, features):
"""
Convert features bitmask to str.
:param features: feature bitmask
:type features: int
:returns: str - the features str of the image
:raises: :class:`InvalidArgument`
"""
cdef:
int ret = -errno.ERANGE
uint64_t _features = features
size_t size = 1024
char *str_features = NULL
try:
while ret == -errno.ERANGE:
str_features = <char *>realloc_chk(str_features, size)
with nogil:
ret = rbd_features_to_string(_features, str_features, &size)
if ret != 0:
raise make_ex(ret, 'error converting features bitmask to str')
return decode_cstr(str_features)
finally:
free(str_features)
def features_from_string(self, str_features):
"""
Get features bitmask from str, if str_features is empty, it will return
RBD_FEATURES_DEFAULT.
:param str_features: feature str
:type str_features: str
:returns: int - the features bitmask of the image
:raises: :class:`InvalidArgument`
"""
str_features = cstr(str_features, 'str_features')
cdef:
const char *_str_features = str_features
uint64_t features
with nogil:
ret = rbd_features_from_string(_str_features, &features)
if ret != 0:
raise make_ex(ret, 'error getting features bitmask from str')
return features
cdef class MirrorPeerIterator(object):
"""

View File

@ -5713,6 +5713,33 @@ TEST_F(TestLibRBD, UpdateFeatures)
ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_DEEP_FLATTEN, true));
}
TEST_F(TestLibRBD, FeaturesBitmaskString)
{
librbd::RBD rbd;
uint64_t features = RBD_FEATURES_DEFAULT;
std::string features_str;
std::string expected_str = "deep-flatten,exclusive-lock,fast-diff,layering,object-map";
rbd.features_to_string(features, &features_str);
ASSERT_EQ(expected_str, features_str);
features = RBD_FEATURE_LAYERING;
features_str = "";
expected_str = "layering";
rbd.features_to_string(features, &features_str);
ASSERT_EQ(expected_str, features_str);
uint64_t features_bitmask;
features_str = "deep-flatten,exclusive-lock,fast-diff,layering,object-map";
rbd.features_from_string(features_str, &features_bitmask);
ASSERT_EQ(features_bitmask, RBD_FEATURES_DEFAULT);
features_str = "layering";
features_bitmask = 0;
rbd.features_from_string(features_str, &features_bitmask);
ASSERT_EQ(features_bitmask, RBD_FEATURE_LAYERING);
}
TEST_F(TestLibRBD, RebuildObjectMap)
{
librados::IoCtx ioctx;

View File

@ -23,6 +23,8 @@ from rbd import (RBD, Group, Image, ImageNotFound, InvalidArgument, ImageExists,
DiskQuotaExceeded, ConnectionShutdown, PermissionError,
RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2,
RBD_FEATURE_EXCLUSIVE_LOCK, RBD_FEATURE_JOURNALING,
RBD_FEATURE_DEEP_FLATTEN, RBD_FEATURE_FAST_DIFF,
RBD_FEATURE_OBJECT_MAP,
RBD_MIRROR_MODE_DISABLED, RBD_MIRROR_MODE_IMAGE,
RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED,
RBD_MIRROR_IMAGE_DISABLED, MIRROR_IMAGE_STATUS_STATE_UNKNOWN,
@ -477,6 +479,35 @@ def check_stat(info, size, order):
eq(info['num_objs'], size // (1 << order))
eq(info['obj_size'], 1 << order)
@require_new_format()
def test_features_to_string():
rbd = RBD()
features = RBD_FEATURE_DEEP_FLATTEN | RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_FAST_DIFF \
| RBD_FEATURE_LAYERING | RBD_FEATURE_OBJECT_MAP
expected_features_string = "deep-flatten,exclusive-lock,fast-diff,layering,object-map"
features_string = rbd.features_to_string(features)
eq(expected_features_string, features_string)
features = RBD_FEATURE_LAYERING
features_string = rbd.features_to_string(features)
eq(features_string, "layering")
features = 1024
assert_raises(InvalidArgument, rbd.features_to_string, features)
@require_new_format()
def test_features_from_string():
rbd = RBD()
features_string = "deep-flatten,exclusive-lock,fast-diff,layering,object-map"
expected_features_bitmask = RBD_FEATURE_DEEP_FLATTEN | RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_FAST_DIFF \
| RBD_FEATURE_LAYERING | RBD_FEATURE_OBJECT_MAP
features = rbd.features_from_string(features_string)
eq(expected_features_bitmask, features)
features_string = "layering"
features = rbd.features_from_string(features_string)
eq(features, RBD_FEATURE_LAYERING)
class TestImage(object):
def setUp(self):