mirror of
https://github.com/ceph/ceph
synced 2025-02-19 17:08:05 +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,
|
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_image_t *image, const char *snap_name,
|
||||||
rbd_completion_t c);
|
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_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_aio_close(rbd_image_t image, rbd_completion_t c);
|
||||||
CEPH_RBD_API int rbd_resize(rbd_image_t image, uint64_t size);
|
CEPH_RBD_API int rbd_resize(rbd_image_t image, uint64_t size);
|
||||||
|
@ -240,6 +240,8 @@ public:
|
|||||||
const char *snapname, RBD::AioCompletion *c);
|
const char *snapname, RBD::AioCompletion *c);
|
||||||
int aio_open_by_id_read_only(IoCtx& io_ctx, Image& image, const char *id,
|
int aio_open_by_id_read_only(IoCtx& io_ctx, Image& image, const char *id,
|
||||||
const char *snapname, RBD::AioCompletion *c);
|
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)
|
int list(IoCtx& io_ctx, std::vector<std::string>& names)
|
||||||
CEPH_RBD_DEPRECATED;
|
CEPH_RBD_DEPRECATED;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "cls/rbd/cls_rbd_client.h"
|
#include "cls/rbd/cls_rbd_client.h"
|
||||||
#include "cls/rbd/cls_rbd_types.h"
|
#include "cls/rbd/cls_rbd_types.h"
|
||||||
|
#include "librbd/Features.h"
|
||||||
#include "librbd/ImageCtx.h"
|
#include "librbd/ImageCtx.h"
|
||||||
#include "librbd/ImageState.h"
|
#include "librbd/ImageState.h"
|
||||||
#include "librbd/internal.h"
|
#include "librbd/internal.h"
|
||||||
@ -621,6 +622,28 @@ namespace librbd {
|
|||||||
return 0;
|
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)
|
int RBD::create(IoCtx& io_ctx, const char *name, uint64_t size, int *order)
|
||||||
{
|
{
|
||||||
TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
|
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;
|
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)
|
extern "C" int rbd_close(rbd_image_t image)
|
||||||
{
|
{
|
||||||
librbd::ImageCtx *ictx = (librbd::ImageCtx *)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)
|
rbd_image_t *image, const char *snap_name)
|
||||||
int rbd_open_by_id_read_only(rados_ioctx_t io, const char *image_id,
|
int rbd_open_by_id_read_only(rados_ioctx_t io, const char *image_id,
|
||||||
rbd_image_t *image, const char *snap_name)
|
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_close(rbd_image_t image)
|
||||||
int rbd_resize2(rbd_image_t image, uint64_t size, bint allow_shrink,
|
int rbd_resize2(rbd_image_t image, uint64_t size, bint allow_shrink,
|
||||||
librbd_progress_fn_t cb, void *cbdata)
|
librbd_progress_fn_t cb, void *cbdata)
|
||||||
@ -2517,6 +2519,52 @@ class RBD(object):
|
|||||||
finally:
|
finally:
|
||||||
rbd_pool_stats_destroy(_stats)
|
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):
|
cdef class MirrorPeerIterator(object):
|
||||||
"""
|
"""
|
||||||
|
@ -5713,6 +5713,33 @@ TEST_F(TestLibRBD, UpdateFeatures)
|
|||||||
ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_DEEP_FLATTEN, true));
|
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)
|
TEST_F(TestLibRBD, RebuildObjectMap)
|
||||||
{
|
{
|
||||||
librados::IoCtx ioctx;
|
librados::IoCtx ioctx;
|
||||||
|
@ -23,6 +23,8 @@ from rbd import (RBD, Group, Image, ImageNotFound, InvalidArgument, ImageExists,
|
|||||||
DiskQuotaExceeded, ConnectionShutdown, PermissionError,
|
DiskQuotaExceeded, ConnectionShutdown, PermissionError,
|
||||||
RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2,
|
RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2,
|
||||||
RBD_FEATURE_EXCLUSIVE_LOCK, RBD_FEATURE_JOURNALING,
|
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_DISABLED, RBD_MIRROR_MODE_IMAGE,
|
||||||
RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED,
|
RBD_MIRROR_MODE_POOL, RBD_MIRROR_IMAGE_ENABLED,
|
||||||
RBD_MIRROR_IMAGE_DISABLED, MIRROR_IMAGE_STATUS_STATE_UNKNOWN,
|
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['num_objs'], size // (1 << order))
|
||||||
eq(info['obj_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):
|
class TestImage(object):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user