]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: new pool mirror API methods
authorJason Dillaman <dillaman@redhat.com>
Thu, 24 Sep 2015 12:39:30 +0000 (08:39 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 2 Dec 2015 16:11:37 +0000 (11:11 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc

index 23aa287353cabe272065dd083656c77d53fbd46c..0a1a5e68273c8a90af6bbbfc937c53e7ff496d5f 100644 (file)
@@ -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);
 
index e04bbe47c619488e6eecb33f7ee05df33820a818..288e450aab86ee0a743b09a488f75fee1d25f90b 100644 (file)
@@ -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<mirror_peer_t> *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);
index 260effcb2c5aeb525e19a2a9e3b05cf3190c0cbe..0b23b51a8df2581aca1d2d5006db9212437ae8a5 100644 (file)
@@ -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<CephContext *>(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<CephContext *>(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<CephContext *>(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<CephContext *>(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<mirror_peer_t> *peers) {
+    CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
+    ldout(cct, 20) << __func__ << dendl;
+
+    std::vector<cls::rbd::MirrorPeer> 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<CephContext *>(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<CephContext *>(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<AioObjectRequest *>(arg);
index bd76e48ddd617dd7a03918b2a7c38ddbec419a1a..a08dd02ab0921f93b279905808b3e04675922419 100644 (file)
@@ -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<mirror_peer_t> *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,
index 35a33c66ecdd3db6fdae4a9972920bd605f88276..f5fd6dfc2dee7b1be65c9ec3180b41ab7a4c8907 100644 (file)
@@ -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<mirror_peer_t> *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<librbd::mirror_peer_t> peer_vector;
+  int r = librbd::mirror_peer_list(io_ctx, &peer_vector);
+  if (r < 0) {
+    return r;
+  }
+
+  if (*max_peers < static_cast<int>(peer_vector.size())) {
+    *max_peers = static_cast<int>(peer_vector.size());
+    return -ERANGE;
+  }
+
+  for (int i = 0; i < static_cast<int>(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<int>(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)
 {