From c12e032549060488a2aefb2e6b720a3d85b31cb9 Mon Sep 17 00:00:00 2001 From: zhengyin Date: Mon, 21 Oct 2019 15:28:00 +0800 Subject: [PATCH] librbd: features converting bitmask and string API Signed-off-by: Zheng Yin --- src/include/rbd/librbd.h | 3 +++ src/include/rbd/librbd.hpp | 2 ++ src/librbd/librbd.cc | 52 ++++++++++++++++++++++++++++++++++++++ src/pybind/rbd/rbd.pyx | 48 +++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 55668b06327..6b887bbb1e6 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -554,6 +554,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); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 15eb9f56a31..bdc2c2384a3 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -212,6 +212,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& names) __attribute__((deprecated)); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index bd8a58e86c1..8ca92202fb3 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -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" @@ -519,6 +520,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(get_cct(io_ctx)); @@ -4124,6 +4147,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; diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 4ebe5b00688..56154b67af2 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -418,6 +418,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) @@ -2413,6 +2415,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 = 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): """ -- 2.39.5