mirror of
https://github.com/ceph/ceph
synced 2025-02-16 07:17:21 +00:00
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:
commit
97db9473fc
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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;
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user