From: Jason Dillaman Date: Thu, 24 Sep 2015 12:39:30 +0000 (-0400) Subject: librbd: new pool mirror API methods X-Git-Tag: v10.0.2~113^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2a3cdbf275bc3decbb14008a5bf7023d1e45b469;p=ceph.git librbd: new pool mirror API methods Signed-off-by: Jason Dillaman --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 23aa287353ca..0a1a5e68273c 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -84,6 +84,12 @@ typedef struct { char parent_name[RBD_MAX_IMAGE_NAME_SIZE]; /* deprecated */ } rbd_image_info_t; +typedef struct { + char *cluster_uuid; + char *cluster_name; + char *client_name; +} rbd_mirror_peer_t; + CEPH_RBD_API void rbd_version(int *major, int *minor, int *extra); /* image options */ @@ -155,6 +161,26 @@ CEPH_RBD_API int rbd_remove_with_progress(rados_ioctx_t io, const char *name, CEPH_RBD_API int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname, const char *destname); +/* pool mirroring */ +CEPH_RBD_API int rbd_mirror_is_enabled(rados_ioctx_t io_ctx, bool *enabled); +CEPH_RBD_API int rbd_mirror_set_enabled(rados_ioctx_t io_ctx, bool enabled); +CEPH_RBD_API int rbd_mirror_peer_add(rados_ioctx_t io_ctx, + const char *cluster_uuid, + const char *cluster_name, + const char *client_name); +CEPH_RBD_API int rbd_mirror_peer_remove(rados_ioctx_t io_ctx, + const char *cluster_name); +CEPH_RBD_API int rbd_mirror_peer_list(rados_ioctx_t io_ctx, + rbd_mirror_peer_t *peers, int *max_peers); +CEPH_RBD_API void rbd_mirror_peer_list_cleanup(rbd_mirror_peer_t *peers, + int max_peers); +CEPH_RBD_API int rbd_mirror_peer_set_client(rados_ioctx_t io_ctx, + const char *cluster_uuid, + const char *client_name); +CEPH_RBD_API int rbd_mirror_peer_set_cluster(rados_ioctx_t io_ctx, + const char *cluster_uuid, + const char *cluster_name); + CEPH_RBD_API int rbd_open(rados_ioctx_t io, const char *name, rbd_image_t *image, const char *snap_name); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index e04bbe47c619..288e450aab86 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -46,6 +46,12 @@ namespace librbd { std::string address; } locker_t; + typedef struct { + std::string cluster_uuid; + std::string cluster_name; + std::string client_name; + } mirror_peer_t; + typedef rbd_image_info_t image_info_t; class CEPH_RBD_API ProgressContext @@ -102,6 +108,19 @@ public: int remove_with_progress(IoCtx& io_ctx, const char *name, ProgressContext& pctx); int rename(IoCtx& src_io_ctx, const char *srcname, const char *destname); + // RBD pool mirroring support functions + int mirror_is_enabled(IoCtx& io_ctx, bool *enabled); + int mirror_set_enabled(IoCtx& io_ctx, bool enabled); + int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name, + const std::string &client_name); + int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid); + int mirror_peer_list(IoCtx& io_ctx, std::vector *peers); + int mirror_peer_set_client(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &client_name); + int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name); + private: /* We don't allow assignment or copying */ RBD(const RBD& rhs); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 260effcb2c5a..0b23b51a8df2 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -3507,6 +3507,130 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type, return cls_client::metadata_list(&ictx->md_ctx, ictx->header_oid, start, max, pairs); } + int mirror_is_enabled(IoCtx& io_ctx, bool *enabled) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << dendl; + + int r = cls_client::mirror_is_enabled(&io_ctx, enabled); + if (r < 0) { + lderr(cct) << "Failed to retrieve mirror flag: " << cpp_strerror(r) + << dendl; + return r; + } + return 0; + } + + int mirror_set_enabled(IoCtx& io_ctx, bool enabled) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << ": enabled=" << enabled << dendl; + + int r = cls_client::mirror_set_enabled(&io_ctx, enabled); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "Failed to set mirror flag: " << cpp_strerror(r) << dendl; + return r; + } + return 0; + } + + int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name, + const std::string &client_name) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", " + << "name=" << cluster_name << ", " + << "client=" << client_name << dendl; + + std::string local_cluster_uuid; + librados::Rados rados(io_ctx); + int r = rados.cluster_fsid(&local_cluster_uuid); + if (r < 0) { + lderr(cct) << "Failed to retreive cluster uuid" << dendl; + return r; + } + + if (local_cluster_uuid == cluster_uuid) { + lderr(cct) << "Cannot add self as remote peer" << dendl; + return -EINVAL; + } + + r = cls_client::mirror_peer_add(&io_ctx, cluster_uuid, cluster_name, + client_name); + if (r < 0) { + lderr(cct) << "Failed to add mirror peer '" << cluster_uuid << "': " + << cpp_strerror(r) << dendl; + return r; + } + return 0; + } + + int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << dendl; + + int r = cls_client::mirror_peer_remove(&io_ctx, cluster_uuid); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "Failed to remove peer '" << cluster_uuid << "': " + << cpp_strerror(r) << dendl; + return r; + } + return 0; + } + + int mirror_peer_list(IoCtx& io_ctx, std::vector *peers) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << dendl; + + std::vector mirror_peers; + int r = cls_client::mirror_peer_list(&io_ctx, &mirror_peers); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "Failed to list peers: " << cpp_strerror(r) << dendl; + return r; + } + + peers->clear(); + peers->reserve(mirror_peers.size()); + for (auto &mirror_peer : mirror_peers) { + mirror_peer_t peer; + peer.cluster_uuid = mirror_peer.cluster_uuid; + peer.cluster_name = mirror_peer.cluster_name; + peer.client_name = mirror_peer.client_name; + peers->push_back(peer); + } + return 0; + } + + int mirror_peer_set_client(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &client_name) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", " + << "client=" << client_name << dendl; + + int r = cls_client::mirror_peer_set_client(&io_ctx, cluster_uuid, + client_name); + if (r < 0) { + lderr(cct) << "Failed to update client '" << cluster_uuid << "': " + << cpp_strerror(r) << dendl; + return r; + } + return 0; + } + + int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", " + << "cluster=" << cluster_name << dendl; + + int r = cls_client::mirror_peer_set_cluster(&io_ctx, cluster_uuid, + cluster_name); + if (r < 0) { + lderr(cct) << "Failed to update cluster '" << cluster_uuid << "': " + << cpp_strerror(r) << dendl; + return r; + } + return 0; + } + void rbd_req_cb(completion_t cb, void *arg) { AioObjectRequest *req = reinterpret_cast(arg); diff --git a/src/librbd/internal.h b/src/librbd/internal.h index bd76e48ddd61..a08dd02ab092 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -216,6 +216,18 @@ namespace librbd { int metadata_set(ImageCtx *ictx, const std::string &key, const std::string &value); int metadata_remove(ImageCtx *ictx, const std::string &key); + int mirror_is_enabled(IoCtx& io_ctx, bool *enabled); + int mirror_set_enabled(IoCtx& io_ctx, bool enabled); + int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name, + const std::string &client_name); + int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid); + int mirror_peer_list(IoCtx& io_ctx, std::vector *peers); + int mirror_peer_set_client(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &client_name); + int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name); + AioCompletion *aio_create_completion(); AioCompletion *aio_create_completion(void *cb_arg, callback_t cb_complete); AioCompletion *aio_create_completion_internal(void *cb_arg, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 35a33c66ecdd..f5fd6dfc2dee 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -277,6 +277,41 @@ namespace librbd { return r; } + int RBD::mirror_is_enabled(IoCtx& io_ctx, bool *enabled) { + return librbd::mirror_is_enabled(io_ctx, enabled); + } + + int RBD::mirror_set_enabled(IoCtx& io_ctx, bool enabled) { + return librbd::mirror_set_enabled(io_ctx, enabled); + } + + int RBD::mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid, + const std::string &cluster_name, + const std::string &client_name) { + return librbd::mirror_peer_add(io_ctx, cluster_uuid, cluster_name, + client_name); + } + + int RBD::mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid) { + return librbd::mirror_peer_remove(io_ctx, cluster_uuid); + } + + int RBD::mirror_peer_list(IoCtx& io_ctx, std::vector *peers) { + return librbd::mirror_peer_list(io_ctx, peers); + } + + int RBD::mirror_peer_set_client(IoCtx& io_ctx, + const std::string &cluster_uuid, + const std::string &client_name) { + return librbd::mirror_peer_set_client(io_ctx, cluster_uuid, client_name); + } + + int RBD::mirror_peer_set_cluster(IoCtx& io_ctx, + const std::string &cluster_uuid, + const std::string &cluster_name) { + return librbd::mirror_peer_set_cluster(io_ctx, cluster_uuid, cluster_name); + } + RBD::AioCompletion::AioCompletion(void *cb_arg, callback_t complete_cb) { librbd::AioCompletion *c = librbd::aio_create_completion(cb_arg, @@ -1131,6 +1166,91 @@ extern "C" int rbd_image_options_is_empty(rbd_image_options_t opts) return librbd::image_options_is_empty(opts); } +/* pool mirroring */ +extern "C" int rbd_mirror_is_enabled(rados_ioctx_t p, bool *enabled) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + int r = librbd::mirror_is_enabled(io_ctx, enabled); + if (r < 0) { + return r; + } + return 0; +} + +extern "C" int rbd_mirror_set_enabled(rados_ioctx_t p, bool enabled) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + return librbd::mirror_set_enabled(io_ctx, enabled); +} + +extern "C" int rbd_mirror_peer_add(rados_ioctx_t p, + const char *cluster_uuid, + const char *cluster_name, + const char *client_name) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + return librbd::mirror_peer_add(io_ctx, cluster_uuid, cluster_name, + client_name); +} + +extern "C" int rbd_mirror_peer_remove(rados_ioctx_t p, + const char *cluster_name) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + int r = librbd::mirror_peer_remove(io_ctx, cluster_name); + return r; +} + +extern "C" int rbd_mirror_peer_list(rados_ioctx_t p, + rbd_mirror_peer_t *peers, int *max_peers) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + + std::vector peer_vector; + int r = librbd::mirror_peer_list(io_ctx, &peer_vector); + if (r < 0) { + return r; + } + + if (*max_peers < static_cast(peer_vector.size())) { + *max_peers = static_cast(peer_vector.size()); + return -ERANGE; + } + + for (int i = 0; i < static_cast(peer_vector.size()); ++i) { + peers[i].cluster_uuid = strdup(peer_vector[i].cluster_uuid.c_str()); + peers[i].cluster_name = strdup(peer_vector[i].cluster_name.c_str()); + peers[i].client_name = strdup(peer_vector[i].client_name.c_str()); + } + *max_peers = static_cast(peer_vector.size()); + return 0; +} + +extern "C" void rbd_mirror_peer_list_cleanup(rbd_mirror_peer_t *peers, + int max_peers) { + for (int i = 0; i < max_peers; ++i) { + free(peers[i].cluster_uuid); + free(peers[i].cluster_name); + free(peers[i].client_name); + } +} + +extern "C" int rbd_mirror_peer_set_client(rados_ioctx_t p, + const char *cluster_uuid, + const char *client_name) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + return librbd::mirror_peer_set_client(io_ctx, cluster_uuid, client_name); +} + +extern "C" int rbd_mirror_peer_set_cluster(rados_ioctx_t p, + const char *cluster_uuid, + const char *cluster_name) { + librados::IoCtx io_ctx; + librados::IoCtx::from_rados_ioctx_t(p, io_ctx); + return librbd::mirror_peer_set_cluster(io_ctx, cluster_uuid, cluster_name); +} + /* images */ extern "C" int rbd_list(rados_ioctx_t p, char *names, size_t *size) {