From: songweibin Date: Thu, 30 Aug 2018 10:17:02 +0000 (+0800) Subject: rbd: add new librbd method to assert namespace exists X-Git-Tag: v14.0.1~439^2~2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=aebd6ed964eb5b0d12ffa29379b921fc7d2e67e3;p=ceph.git rbd: add new librbd method to assert namespace exists Signed-off-by: songweibin --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 66d5444e943ac..85e9636f42656 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -1045,6 +1045,8 @@ CEPH_RBD_API int rbd_namespace_remove(rados_ioctx_t io, const char *namespace_name); CEPH_RBD_API int rbd_namespace_list(rados_ioctx_t io, char *namespace_names, size_t *size); +CEPH_RBD_API int rbd_namespace_exists(rados_ioctx_t io, const char *namespace_name, + bool *exists); #ifdef __cplusplus } diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index c6270d33109ad..38cc707a31f03 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -271,6 +271,7 @@ public: int namespace_create(IoCtx& ioctx, const char *namespace_name); int namespace_remove(IoCtx& ioctx, const char *namespace_name); int namespace_list(IoCtx& io_ctx, std::vector* namespace_names); + int namespace_exists(IoCtx& io_ctx, const char *namespace_name, bool *exists); private: /* We don't allow assignment or copying */ diff --git a/src/librbd/api/Namespace.cc b/src/librbd/api/Namespace.cc index f73ae845486c2..040adb8706197 100644 --- a/src/librbd/api/Namespace.cc +++ b/src/librbd/api/Namespace.cc @@ -155,6 +155,34 @@ int Namespace::list(IoCtx& io_ctx, vector *names) return 0; } +template +int Namespace::exists(librados::IoCtx& io_ctx, const std::string& name, bool *exists) +{ + CephContext *cct = (CephContext *)io_ctx.cct(); + ldout(cct, 5) << "name=" << name << dendl; + + if (name.empty()) { + return -EINVAL; + } + + librados::IoCtx ns_ctx; + ns_ctx.dup(io_ctx); + ns_ctx.set_namespace(name); + + int r = librbd::cls_client::dir_state_assert(&ns_ctx, RBD_DIRECTORY, + cls::rbd::DIRECTORY_STATE_READY); + if (r == 0) { + *exists = true; + } else if (r == -ENOENT) { + *exists = false; + } else { + lderr(cct) << "error asserting namespace: " << cpp_strerror(r) << dendl; + return r; + } + + return 0; +} + } // namespace api } // namespace librbd diff --git a/src/librbd/api/Namespace.h b/src/librbd/api/Namespace.h index c892a3bc11ef1..e26cb687be170 100644 --- a/src/librbd/api/Namespace.h +++ b/src/librbd/api/Namespace.h @@ -22,6 +22,7 @@ struct Namespace { static int create(librados::IoCtx& io_ctx, const std::string& name); static int remove(librados::IoCtx& io_ctx, const std::string& name); static int list(librados::IoCtx& io_ctx, std::vector* names); + static int exists(librados::IoCtx& io_ctx, const std::string& name, bool *exists); }; diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 9616be97f8386..785259afb260e 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -630,6 +630,11 @@ namespace librbd { return librbd::api::Namespace<>::list(io_ctx, namespace_names); } + int RBD::namespace_exists(IoCtx& io_ctx, const char *namespace_name, + bool *exists) { + return librbd::api::Namespace<>::exists(io_ctx, namespace_name, exists); + } + int RBD::list(IoCtx& io_ctx, vector& names) { TracepointProvider::initialize(get_cct(io_ctx)); @@ -2899,6 +2904,15 @@ extern "C" int rbd_namespace_list(rados_ioctx_t io, char *names, size_t *size) { return (int)expected_size; } +extern "C" int rbd_namespace_exists(rados_ioctx_t io, + const char *namespace_name, + bool *exists) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(io, io_ctx); + + return librbd::api::Namespace<>::exists(io_ctx, namespace_name, exists); +} + extern "C" int rbd_copy(rbd_image_t image, rados_ioctx_t dest_p, const char *destname) { diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 6d33b28393bcd..c882a4f85f686 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -6752,6 +6752,11 @@ TEST_F(TestLibRBD, Namespaces) { ASSERT_EQ(2U, cpp_names.size()); ASSERT_EQ("name1", cpp_names[0]); ASSERT_EQ("name3", cpp_names[1]); + bool exists; + ASSERT_EQ(0, rbd_namespace_exists(ioctx, "name2", &exists)); + ASSERT_FALSE(exists); + ASSERT_EQ(0, rbd_namespace_exists(ioctx, "name3", &exists)); + ASSERT_TRUE(exists); rados_ioctx_destroy(ioctx); } @@ -6776,6 +6781,11 @@ TEST_F(TestLibRBD, NamespacesPP) { ASSERT_EQ(2U, names.size()); ASSERT_EQ("name1", names[0]); ASSERT_EQ("name3", names[1]); + bool exists; + ASSERT_EQ(0, rbd.namespace_exists(ioctx, "name2", &exists)); + ASSERT_FALSE(exists); + ASSERT_EQ(0, rbd.namespace_exists(ioctx, "name3", &exists)); + ASSERT_TRUE(exists); librados::IoCtx ns_io_ctx; ns_io_ctx.dup(ioctx);