From 25c5dfbbfca2cffedd33073c31c2adcd1a87ed9d Mon Sep 17 00:00:00 2001 From: zhengyin Date: Thu, 31 Oct 2019 18:32:43 +0800 Subject: [PATCH] librbd: add snap_get_name and snap_get_id method API Signed-off-by: Zheng Yin --- src/include/rbd/librbd.h | 2 ++ src/include/rbd/librbd.hpp | 2 ++ src/librbd/api/Snapshot.cc | 32 ++++++++++++++++++++++++ src/librbd/api/Snapshot.h | 4 +++ src/librbd/librbd.cc | 34 ++++++++++++++++++++++++++ src/pybind/rbd/rbd.pyx | 50 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+) diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 55668b06327..9bfb89557ad 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -733,6 +733,8 @@ CEPH_RBD_API int rbd_snap_get_timestamp(rbd_image_t image, uint64_t snap_id, str CEPH_RBD_API int rbd_snap_set(rbd_image_t image, const char *snapname); CEPH_RBD_API int rbd_snap_set_by_id(rbd_image_t image, uint64_t snap_id); +CEPH_RBD_API int rbd_snap_get_name(rbd_image_t image, uint64_t snap_id, char *snapname, size_t *name_len); +CEPH_RBD_API int rbd_snap_get_id(rbd_image_t image, const char *snapname, uint64_t *snap_id); CEPH_RBD_API int rbd_snap_get_namespace_type(rbd_image_t image, uint64_t snap_id, diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 15eb9f56a31..ff13b439f40 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -523,6 +523,8 @@ public: int snap_is_protected(const char *snap_name, bool *is_protected); int snap_set(const char *snap_name); int snap_set_by_id(uint64_t snap_id); + int snap_get_name(uint64_t snap_id, std::string *snap_name); + int snap_get_id(const std::string snap_name, uint64_t *snap_id); int snap_rename(const char *srcname, const char *dstname); int snap_get_limit(uint64_t *limit); int snap_set_limit(uint64_t limit); diff --git a/src/librbd/api/Snapshot.cc b/src/librbd/api/Snapshot.cc index 8ca4c52be3c..2219d8f1a66 100644 --- a/src/librbd/api/Snapshot.cc +++ b/src/librbd/api/Snapshot.cc @@ -190,6 +190,38 @@ int Snapshot::remove(I *ictx, uint64_t snap_id) { return r; } +template +int Snapshot::get_name(I *ictx, uint64_t snap_id, std::string *snap_name) + { + ldout(ictx->cct, 20) << "snap_get_name " << ictx << " " << snap_id << dendl; + + int r = ictx->state->refresh_if_required(); + if (r < 0) + return r; + + std::shared_lock image_locker{ictx->image_lock}; + r = ictx->get_snap_name(snap_id, snap_name); + + return r; + } + +template +int Snapshot::get_id(I *ictx, const std::string& snap_name, uint64_t *snap_id) + { + ldout(ictx->cct, 20) << "snap_get_id " << ictx << " " << snap_name << dendl; + + int r = ictx->state->refresh_if_required(); + if (r < 0) + return r; + + std::shared_lock image_locker{ictx->image_lock}; + *snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(), snap_name); + if (*snap_id == CEPH_NOSNAP) + return -ENOENT; + + return 0; + } + } // namespace api } // namespace librbd diff --git a/src/librbd/api/Snapshot.h b/src/librbd/api/Snapshot.h index 453861c4008..8a6696578ac 100644 --- a/src/librbd/api/Snapshot.h +++ b/src/librbd/api/Snapshot.h @@ -27,6 +27,10 @@ struct Snapshot { static int remove(ImageCtxT *ictx, uint64_t snap_id); + static int get_name(ImageCtxT *ictx, uint64_t snap_id, std::string *snap_name); + + static int get_id(ImageCtxT *ictx, const std::string& snap_name, uint64_t *snap_id); + }; } // namespace api diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index bd8a58e86c1..3e53dda20f6 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -2135,6 +2135,18 @@ namespace librbd { return librbd::api::Image<>::snap_set(ictx, snap_id); } + int Image::snap_get_name(uint64_t snap_id, std::string *snap_name) + { + ImageCtx *ictx = (ImageCtx *)ctx; + return librbd::api::Snapshot<>::get_name(ictx, snap_id, snap_name); + } + + int Image::snap_get_id(const std::string snap_name, uint64_t *snap_id) + { + ImageCtx *ictx = (ImageCtx *)ctx; + return librbd::api::Snapshot<>::get_id(ictx, snap_name, snap_id); + } + ssize_t Image::read(uint64_t ofs, size_t len, bufferlist& bl) { ImageCtx *ictx = (ImageCtx *)ctx; @@ -4818,6 +4830,28 @@ extern "C" int rbd_snap_set_by_id(rbd_image_t image, uint64_t snap_id) return librbd::api::Image<>::snap_set(ictx, snap_id); } +extern "C" int rbd_snap_get_name(rbd_image_t image, uint64_t snap_id, char *snapname, size_t *name_len) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + std::string snap_name; + int r = librbd::api::Snapshot<>::get_name(ictx, snap_id, &snap_name); + size_t expected_size = snap_name.size(); + if (*name_len <= expected_size) { + *name_len = expected_size + 1; + return -ERANGE; + } + strncpy(snapname, snap_name.c_str(), expected_size); + snapname[expected_size] = '\0'; + *name_len = expected_size + 1; + return r; +} + +extern "C" int rbd_snap_get_id(rbd_image_t image, const char *snapname, uint64_t *snap_id) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + return librbd::api::Snapshot<>::get_id(ictx, snapname, snap_id); +} + extern "C" ssize_t rbd_list_children(rbd_image_t image, char *pools, size_t *pools_len, char *images, size_t *images_len) diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 4ebe5b00688..9742b754863 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -475,6 +475,10 @@ cdef extern from "rbd/librbd.h" nogil: int rbd_snap_get_timestamp(rbd_image_t image, uint64_t snap_id, timespec *timestamp) int rbd_snap_set(rbd_image_t image, const char *snapname) int rbd_snap_set_by_id(rbd_image_t image, uint64_t snap_id) + int rbd_snap_get_name(rbd_image_t image, uint64_t snap_id, + char *snapname, size_t *name_len) + int rbd_snap_get_id(rbd_image_t image, const char *snapname, + uint64_t *snap_id) int rbd_snap_get_namespace_type(rbd_image_t image, uint64_t snap_id, rbd_snap_namespace_type_t *namespace_type) @@ -3749,6 +3753,52 @@ cdef class Image(object): if ret != 0: raise make_ex(ret, 'error setting image %s to snapshot %d' % (self.name, snap_id)) + def snap_get_name(self, snap_id): + """ + Get snapshot name by id. + + :param snap_id: the snapshot id + :type snap_id: int + :returns: str - snapshot name + :raises: :class:`ImageNotFound` + """ + cdef: + int ret = -errno.ERANGE + int64_t _snap_id = snap_id + size_t size = 512 + char *image_name = NULL + try: + while ret == -errno.ERANGE: + image_name = realloc_chk(image_name, size) + with nogil: + ret = rbd_snap_get_name(self.image, _snap_id, image_name, &size) + + if ret != 0: + raise make_ex(ret, 'error snap_get_name.') + return decode_cstr(image_name) + finally: + free(image_name) + + def snap_get_id(self, snap_name): + """ + Get snapshot id by name. + + :param snap_name: the snapshot name + :type snap_name: str + :returns: int - snapshot id + :raises: :class:`ImageNotFound` + """ + + snap_name = cstr(snap_name, 'snap_name') + cdef: + const char *_snap_name = snap_name + uint64_t snap_id + with nogil: + ret = rbd_snap_get_id(self.image, _snap_name, &snap_id) + if ret != 0: + raise make_ex(ret, 'error snap_get_id.') + return snap_id + def read(self, offset, length, fadvise_flags=0): """ Read data from the image. Raises :class:`InvalidArgument` if -- 2.39.5