return 0;
}
-int read_peer(cls_method_context_t hctx, const std::string &uuid,
+int read_peer(cls_method_context_t hctx, const std::string &id,
cls::rbd::MirrorPeer *peer) {
bufferlist bl;
- int r = cls_cxx_map_get_val(hctx, peer_key(uuid), &bl);
+ int r = cls_cxx_map_get_val(hctx, peer_key(id), &bl);
if (r < 0) {
- CLS_ERR("error reading peer '%s': %s", uuid.c_str(),
+ CLS_ERR("error reading peer '%s': %s", id.c_str(),
cpp_strerror(r).c_str());
return r;
}
bufferlist::iterator bl_it = bl.begin();
::decode(*peer, bl_it);
} catch (const buffer::error &err) {
- CLS_ERR("could not decode peer '%s'", uuid.c_str());
+ CLS_ERR("could not decode peer '%s'", id.c_str());
return -EIO;
}
return 0;
}
-int write_peer(cls_method_context_t hctx, const std::string &uuid,
+int write_peer(cls_method_context_t hctx, const std::string &id,
const cls::rbd::MirrorPeer &peer) {
bufferlist bl;
::encode(peer, bl);
- int r = cls_cxx_map_set_val(hctx, peer_key(uuid), &bl);
+ int r = cls_cxx_map_set_val(hctx, peer_key(id), &bl);
if (r < 0) {
- CLS_ERR("error writing peer '%s': %s", uuid.c_str(),
+ CLS_ERR("error writing peer '%s': %s", id.c_str(),
cpp_strerror(r).c_str());
return r;
}
}
for (auto const &peer : peers) {
- if (peer.cluster_uuid == mirror_peer.cluster_uuid) {
- CLS_ERR("peer cluster uuid '%s' alread exists",
- peer.cluster_uuid.c_str());
- return -EEXIST;
- } else if (peer.cluster_name == mirror_peer.cluster_name) {
- CLS_ERR("peer cluster name '%s' alread exists",
+ if (peer.uuid == mirror_peer.uuid) {
+ CLS_ERR("peer uuid '%s' already exists",
+ peer.uuid.c_str());
+ return -ESTALE;
+ } else if (peer.cluster_name == mirror_peer.cluster_name &&
+ (peer.pool_id == -1 || mirror_peer.pool_id == -1 ||
+ peer.pool_id == mirror_peer.pool_id)) {
+ CLS_ERR("peer cluster name '%s' already exists",
peer.cluster_name.c_str());
return -EEXIST;
}
bufferlist bl;
::encode(mirror_peer, bl);
- r = cls_cxx_map_set_val(hctx, mirror::peer_key(mirror_peer.cluster_uuid),
+ r = cls_cxx_map_set_val(hctx, mirror::peer_key(mirror_peer.uuid),
&bl);
if (r < 0) {
CLS_ERR("error adding peer: %s", cpp_strerror(r).c_str());
/**
* Input:
- * @param cluster_uuid (std::string)
+ * @param uuid (std::string)
*
* Output:
* @returns 0 on success, negative error code on failure
*/
int mirror_peer_remove(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
- std::string cluster_uuid;
+ std::string uuid;
try {
bufferlist::iterator it = in->begin();
- ::decode(cluster_uuid, it);
+ ::decode(uuid, it);
} catch (const buffer::error &err) {
return -EINVAL;
}
- int r = cls_cxx_map_remove_key(hctx, mirror::peer_key(cluster_uuid));
+ int r = cls_cxx_map_remove_key(hctx, mirror::peer_key(uuid));
if (r < 0 && r != -ENOENT) {
CLS_ERR("error removing peer: %s", cpp_strerror(r).c_str());
return r;
/**
* Input:
- * @param cluster_uuid (std::string)
+ * @param uuid (std::string)
* @param client_name (std::string)
*
* Output:
*/
int mirror_peer_set_client(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
- std::string cluster_uuid;
+ std::string uuid;
std::string client_name;
try {
bufferlist::iterator it = in->begin();
- ::decode(cluster_uuid, it);
+ ::decode(uuid, it);
::decode(client_name, it);
} catch (const buffer::error &err) {
return -EINVAL;
}
cls::rbd::MirrorPeer peer;
- int r = mirror::read_peer(hctx, cluster_uuid, &peer);
+ int r = mirror::read_peer(hctx, uuid, &peer);
if (r < 0) {
return r;
}
peer.client_name = client_name;
- r = mirror::write_peer(hctx, cluster_uuid, peer);
+ r = mirror::write_peer(hctx, uuid, peer);
if (r < 0) {
return r;
}
/**
* Input:
- * @param cluster_uuid (std::string)
+ * @param uuid (std::string)
* @param cluster_name (std::string)
*
* Output:
*/
int mirror_peer_set_cluster(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
- std::string cluster_uuid;
+ std::string uuid;
std::string cluster_name;
try {
bufferlist::iterator it = in->begin();
- ::decode(cluster_uuid, it);
+ ::decode(uuid, it);
::decode(cluster_name, it);
} catch (const buffer::error &err) {
return -EINVAL;
}
cls::rbd::MirrorPeer peer;
- int r = mirror::read_peer(hctx, cluster_uuid, &peer);
+ int r = mirror::read_peer(hctx, uuid, &peer);
if (r < 0) {
return r;
}
peer.cluster_name = cluster_name;
- r = mirror::write_peer(hctx, cluster_uuid, peer);
+ r = mirror::write_peer(hctx, uuid, peer);
if (r < 0) {
return r;
}
return 0;
}
- int mirror_peer_add(librados::IoCtx *ioctx, const std::string &cluster_uuid,
+ int mirror_peer_add(librados::IoCtx *ioctx, const std::string &uuid,
const std::string &cluster_name,
- const std::string &client_name) {
- cls::rbd::MirrorPeer peer(cluster_uuid, cluster_name, client_name);
+ const std::string &client_name, int64_t pool_id) {
+ cls::rbd::MirrorPeer peer(uuid, cluster_name, client_name, pool_id);
bufferlist in_bl;
::encode(peer, in_bl);
}
int mirror_peer_remove(librados::IoCtx *ioctx,
- const std::string &cluster_uuid) {
+ const std::string &uuid) {
bufferlist in_bl;
- ::encode(cluster_uuid, in_bl);
+ ::encode(uuid, in_bl);
bufferlist out_bl;
int r = ioctx->exec(RBD_POOL_SETTINGS, "rbd", "mirror_peer_remove", in_bl,
}
int mirror_peer_set_client(librados::IoCtx *ioctx,
- const std::string &cluster_uuid,
+ const std::string &uuid,
const std::string &client_name) {
bufferlist in_bl;
- ::encode(cluster_uuid, in_bl);
+ ::encode(uuid, in_bl);
::encode(client_name, in_bl);
bufferlist out_bl;
}
int mirror_peer_set_cluster(librados::IoCtx *ioctx,
- const std::string &cluster_uuid,
+ const std::string &uuid,
const std::string &cluster_name) {
bufferlist in_bl;
- ::encode(cluster_uuid, in_bl);
+ ::encode(uuid, in_bl);
::encode(cluster_name, in_bl);
bufferlist out_bl;
cls::rbd::MirrorMode mirror_mode);
int mirror_peer_list(librados::IoCtx *ioctx,
std::vector<cls::rbd::MirrorPeer> *peers);
- int mirror_peer_add(librados::IoCtx *ioctx, const std::string &cluster_uuid,
+ int mirror_peer_add(librados::IoCtx *ioctx, const std::string &uuid,
const std::string &cluster_name,
- const std::string &client_name);
+ const std::string &client_name,
+ int64_t pool_id = -1);
int mirror_peer_remove(librados::IoCtx *ioctx,
- const std::string &cluster_uuid);
+ const std::string &uuid);
int mirror_peer_set_client(librados::IoCtx *ioctx,
- const std::string &cluster_uuid,
+ const std::string &uuid,
const std::string &client_name);
int mirror_peer_set_cluster(librados::IoCtx *ioctx,
- const std::string &cluster_uuid,
+ const std::string &uuid,
const std::string &cluster_name);
} // namespace cls_client
void MirrorPeer::encode(bufferlist &bl) const {
ENCODE_START(1, 1, bl);
- ::encode(cluster_uuid, bl);
+ ::encode(uuid, bl);
::encode(cluster_name, bl);
::encode(client_name, bl);
+ ::encode(pool_id, bl);
ENCODE_FINISH(bl);
}
void MirrorPeer::decode(bufferlist::iterator &it) {
DECODE_START(1, it);
- ::decode(cluster_uuid, it);
+ ::decode(uuid, it);
::decode(cluster_name, it);
::decode(client_name, it);
+ ::decode(pool_id, it);
DECODE_FINISH(it);
}
void MirrorPeer::dump(Formatter *f) const {
- f->dump_string("cluster_uuid", cluster_uuid);
+ f->dump_string("uuid", uuid);
f->dump_string("cluster_name", cluster_name);
f->dump_string("client_name", client_name);
+ f->dump_int("pool_id", pool_id);
}
void MirrorPeer::generate_test_instances(std::list<MirrorPeer*> &o) {
o.push_back(new MirrorPeer());
- o.push_back(new MirrorPeer("uuid-123", "cluster name", "client name"));
+ o.push_back(new MirrorPeer("uuid-123", "cluster name", "client name", 123));
}
bool MirrorPeer::operator==(const MirrorPeer &rhs) const {
- return (cluster_uuid == rhs.cluster_uuid &&
+ return (uuid == rhs.uuid &&
cluster_name == rhs.cluster_name &&
- client_name == rhs.client_name);
+ client_name == rhs.client_name &&
+ pool_id == rhs.pool_id);
}
std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode) {
std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer) {
os << "["
- << "cluster_uuid=" << peer.cluster_uuid << ", "
+ << "uuid=" << peer.uuid << ", "
<< "cluster_name=" << peer.cluster_name << ", "
- << "client_name=" << peer.client_name << "]";
+ << "client_name=" << peer.client_name;
+ if (peer.pool_id != -1) {
+ os << ", pool_id=" << peer.pool_id;
+ }
+ os << "]";
return os;
}
struct MirrorPeer {
MirrorPeer() {
}
- MirrorPeer(const std::string &cluster_uuid, const std::string &cluster_name,
- const std::string &client_name)
- : cluster_uuid(cluster_uuid), cluster_name(cluster_name),
- client_name(client_name) {
+ MirrorPeer(const std::string &uuid, const std::string &cluster_name,
+ const std::string &client_name, int64_t pool_id)
+ : uuid(uuid), cluster_name(cluster_name), client_name(client_name),
+ pool_id(pool_id) {
}
- std::string cluster_uuid;
+ std::string uuid;
std::string cluster_name;
std::string client_name;
+ int64_t pool_id = -1;
void encode(bufferlist &bl) const;
void decode(bufferlist::iterator &it);
} rbd_mirror_mode_t;
typedef struct {
- char *cluster_uuid;
+ char *uuid;
char *cluster_name;
char *client_name;
} rbd_mirror_peer_t;
CEPH_RBD_API int rbd_mirror_mode_set(rados_ioctx_t io_ctx,
rbd_mirror_mode_t mirror_mode);
CEPH_RBD_API int rbd_mirror_peer_add(rados_ioctx_t io_ctx,
- const char *cluster_uuid,
+ char *uuid, size_t uuid_max_length,
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);
+ const char *uuid);
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 *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 *uuid,
const char *cluster_name);
CEPH_RBD_API int rbd_open(rados_ioctx_t io, const char *name,
} locker_t;
typedef struct {
- std::string cluster_uuid;
+ std::string uuid;
std::string cluster_name;
std::string client_name;
} mirror_peer_t;
// RBD pool mirroring support functions
int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
- int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int mirror_peer_add(IoCtx& io_ctx, std::string *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_remove(IoCtx& io_ctx, const std::string &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,
+ int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
const std::string &client_name);
- int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
const std::string &cluster_name);
private:
#include <limits.h>
#include "include/types.h"
+#include "include/uuid.h"
#include "common/ceph_context.h"
#include "common/dout.h"
#include "common/errno.h"
return 0;
}
- int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int mirror_peer_add(IoCtx& io_ctx, std::string *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 << ", "
+ ldout(cct, 20) << __func__ << ": "
<< "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) {
+ if (cct->_conf->cluster == cluster_name) {
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;
- }
+ int r;
+ do {
+ uuid_d uuid_gen;
+ uuid_gen.generate_random();
+
+ *uuid = uuid_gen.to_string();
+ r = cls_client::mirror_peer_add(&io_ctx, *uuid, cluster_name,
+ client_name);
+ if (r == -ESTALE) {
+ ldout(cct, 5) << "Duplicate UUID detected, retrying" << dendl;
+ } else if (r < 0) {
+ lderr(cct) << "Failed to add mirror peer '" << uuid << "': "
+ << cpp_strerror(r) << dendl;
+ return r;
+ }
+ } while (r == -ESTALE);
return 0;
}
- int mirror_peer_remove(IoCtx& io_ctx, const std::string &cluster_uuid) {
+ int mirror_peer_remove(IoCtx& io_ctx, const std::string &uuid) {
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
- ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << dendl;
+ ldout(cct, 20) << __func__ << ": uuid=" << uuid << dendl;
- int r = cls_client::mirror_peer_remove(&io_ctx, cluster_uuid);
+ int r = cls_client::mirror_peer_remove(&io_ctx, uuid);
if (r < 0 && r != -ENOENT) {
- lderr(cct) << "Failed to remove peer '" << cluster_uuid << "': "
+ lderr(cct) << "Failed to remove peer '" << uuid << "': "
<< cpp_strerror(r) << dendl;
return r;
}
peers->reserve(mirror_peers.size());
for (auto &mirror_peer : mirror_peers) {
mirror_peer_t peer;
- peer.cluster_uuid = mirror_peer.cluster_uuid;
+ peer.uuid = mirror_peer.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,
+ int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
const std::string &client_name) {
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
- ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", "
+ ldout(cct, 20) << __func__ << ": uuid=" << uuid << ", "
<< "client=" << client_name << dendl;
- int r = cls_client::mirror_peer_set_client(&io_ctx, cluster_uuid,
- client_name);
+ int r = cls_client::mirror_peer_set_client(&io_ctx, uuid, client_name);
if (r < 0) {
- lderr(cct) << "Failed to update client '" << cluster_uuid << "': "
+ lderr(cct) << "Failed to update client '" << uuid << "': "
<< cpp_strerror(r) << dendl;
return r;
}
return 0;
}
- int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
const std::string &cluster_name) {
CephContext *cct = reinterpret_cast<CephContext *>(io_ctx.cct());
- ldout(cct, 20) << __func__ << ": uuid=" << cluster_uuid << ", "
+ ldout(cct, 20) << __func__ << ": uuid=" << uuid << ", "
<< "cluster=" << cluster_name << dendl;
- int r = cls_client::mirror_peer_set_cluster(&io_ctx, cluster_uuid,
- cluster_name);
+ int r = cls_client::mirror_peer_set_cluster(&io_ctx, uuid, cluster_name);
if (r < 0) {
- lderr(cct) << "Failed to update cluster '" << cluster_uuid << "': "
+ lderr(cct) << "Failed to update cluster '" << uuid << "': "
<< cpp_strerror(r) << dendl;
return r;
}
int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
- int mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int mirror_peer_add(IoCtx& io_ctx, std::string *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_remove(IoCtx& io_ctx, const std::string &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,
+ int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
const std::string &client_name);
- int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
const std::string &cluster_name);
}
return librbd::mirror_mode_set(io_ctx, mirror_mode);
}
- int RBD::mirror_peer_add(IoCtx& io_ctx, const std::string &cluster_uuid,
+ int RBD::mirror_peer_add(IoCtx& io_ctx, std::string *uuid,
const std::string &cluster_name,
const std::string &client_name) {
- return librbd::mirror_peer_add(io_ctx, cluster_uuid, cluster_name,
- client_name);
+ return librbd::mirror_peer_add(io_ctx, 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_remove(IoCtx& io_ctx, const std::string &uuid) {
+ return librbd::mirror_peer_remove(io_ctx, 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,
+ int RBD::mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid,
const std::string &client_name) {
- return librbd::mirror_peer_set_client(io_ctx, cluster_uuid, client_name);
+ return librbd::mirror_peer_set_client(io_ctx, uuid, client_name);
}
- int RBD::mirror_peer_set_cluster(IoCtx& io_ctx,
- const std::string &cluster_uuid,
+ int RBD::mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid,
const std::string &cluster_name) {
- return librbd::mirror_peer_set_cluster(io_ctx, cluster_uuid, cluster_name);
+ return librbd::mirror_peer_set_cluster(io_ctx, uuid, cluster_name);
}
RBD::AioCompletion::AioCompletion(void *cb_arg, callback_t complete_cb)
return librbd::mirror_mode_set(io_ctx, mirror_mode);
}
-extern "C" int rbd_mirror_peer_add(rados_ioctx_t p,
- const char *cluster_uuid,
+extern "C" int rbd_mirror_peer_add(rados_ioctx_t p, char *uuid,
+ size_t uuid_max_length,
const char *cluster_name,
const char *client_name) {
+ static const std::size_t UUID_LENGTH = 36;
+
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);
+
+ if (uuid_max_length < UUID_LENGTH + 1) {
+ return -E2BIG;
+ }
+
+ std::string uuid_str;
+ int r = librbd::mirror_peer_add(io_ctx, &uuid_str, cluster_name, client_name);
+ if (r >= 0) {
+ strncpy(uuid, uuid_str.c_str(), uuid_max_length);
+ uuid[uuid_max_length - 1] = '\0';
+ }
+ return r;
}
-extern "C" int rbd_mirror_peer_remove(rados_ioctx_t p,
- const char *cluster_name) {
+extern "C" int rbd_mirror_peer_remove(rados_ioctx_t p, const char *uuid) {
librados::IoCtx io_ctx;
librados::IoCtx::from_rados_ioctx_t(p, io_ctx);
- int r = librbd::mirror_peer_remove(io_ctx, cluster_name);
+ int r = librbd::mirror_peer_remove(io_ctx, uuid);
return r;
}
}
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].uuid = strdup(peer_vector[i].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());
}
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].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,
+extern "C" int rbd_mirror_peer_set_client(rados_ioctx_t p, const char *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);
+ return librbd::mirror_peer_set_client(io_ctx, uuid, client_name);
}
-extern "C" int rbd_mirror_peer_set_cluster(rados_ioctx_t p,
- const char *cluster_uuid,
+extern "C" int rbd_mirror_peer_set_cluster(rados_ioctx_t p, const char *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);
+ return librbd::mirror_peer_set_cluster(io_ctx, uuid, cluster_name);
}
/* images */
usage: rbd mirror pool peer add [--pool <pool>]
[--remote-client-name <remote-client-name>]
[--remote-cluster <remote-cluster>]
- [--remote-cluster-uuid <remote-cluster-uuid>]
<pool-name> <remote-cluster-spec>
Add a mirroring peer to a pool.
Positional arguments
- <pool-name> pool name
- <remote-cluster-spec> remote cluster spec
- (example: [<client name>@]<cluster name>
+ <pool-name> pool name
+ <remote-cluster-spec> remote cluster spec
+ (example: [<client name>@]<cluster name>
Optional arguments
- -p [ --pool ] arg pool name
- --remote-client-name arg remote client name
- --remote-cluster arg remote cluster name
- --remote-cluster-uuid arg remote cluster uuid
+ -p [ --pool ] arg pool name
+ --remote-client-name arg remote client name
+ --remote-cluster arg remote cluster name
rbd help mirror pool peer remove
usage: rbd mirror pool peer remove [--pool <pool>]
- <pool-name> <cluster-uuid>
+ <pool-name> <uuid>
Remove a mirroring peer from a pool.
Positional arguments
<pool-name> pool name
- <cluster-uuid> cluster UUID
+ <uuid> peer uuid
Optional arguments
-p [ --pool ] arg pool name
rbd help mirror pool peer set
usage: rbd mirror pool peer set [--pool <pool>]
- <pool-name> <cluster-uuid> <key> <value>
+ <pool-name> <uuid> <key> <value>
Update mirroring peer settings.
Positional arguments
<pool-name> pool name
- <cluster-uuid> cluster UUID
+ <uuid> peer uuid
<key> peer parameter [client or cluster]
<value> new client or cluster name
rbd: remote cluster was not specified
[22]
$ rbd mirror pool peer remove rbd
- rbd: must specify cluster uuid
+ rbd: must specify peer uuid
[22]
ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid1", "cluster1", "client"));
ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid2", "cluster2", "admin"));
- ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid2", "cluster3", "foo"));
+ ASSERT_EQ(-ESTALE, mirror_peer_add(&ioctx, "uuid2", "cluster3", "foo"));
ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid3", "cluster1", "foo"));
- ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid3", "cluster3", "admin"));
+ ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid3", "cluster3", "admin", 123));
+ ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid4", "cluster3", "admin"));
+ ASSERT_EQ(-EEXIST, mirror_peer_add(&ioctx, "uuid4", "cluster3", "admin", 123));
+ ASSERT_EQ(0, mirror_peer_add(&ioctx, "uuid4", "cluster3", "admin", 234));
ASSERT_EQ(0, mirror_peer_list(&ioctx, &peers));
std::vector<cls::rbd::MirrorPeer> expected_peers = {
- {"uuid1", "cluster1", "client"},
- {"uuid2", "cluster2", "admin"},
- {"uuid3", "cluster3", "admin"}};
+ {"uuid1", "cluster1", "client", -1},
+ {"uuid2", "cluster2", "admin", -1},
+ {"uuid3", "cluster3", "admin", 123},
+ {"uuid4", "cluster3", "admin", 234}};
ASSERT_EQ(expected_peers, peers);
+ ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid5"));
ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid4"));
ASSERT_EQ(0, mirror_peer_remove(&ioctx, "uuid2"));
ASSERT_EQ(0, mirror_peer_list(&ioctx, &peers));
expected_peers = {
- {"uuid1", "cluster1", "new client"},
- {"uuid3", "new cluster", "admin"}};
+ {"uuid1", "cluster1", "new client", -1},
+ {"uuid3", "new cluster", "admin", 123}};
ASSERT_EQ(expected_peers, peers);
ASSERT_EQ(-EBUSY, mirror_mode_set(&ioctx, cls::rbd::MIRROR_MODE_DISABLED));
namespace librbd {
static bool operator==(const mirror_peer_t &lhs, const mirror_peer_t &rhs) {
- return (lhs.cluster_uuid == rhs.cluster_uuid &&
+ return (lhs.uuid == rhs.uuid &&
lhs.cluster_name == rhs.cluster_name &&
lhs.client_name == rhs.client_name);
}
+static std::ostream& operator<<(std::ostream &os, const mirror_peer_t &peer) {
+ os << "uuid=" << peer.uuid << ", "
+ << "cluster=" << peer.cluster_name << ", "
+ << "client=" << peer.client_name;
+ return os;
+}
+
} // namespace librbd
TEST_F(TestLibRBD, Mirror) {
ASSERT_EQ(0, rbd.mirror_peer_list(ioctx, &peers));
ASSERT_EQ(expected_peers, peers);
- ASSERT_EQ(-EINVAL, rbd.mirror_peer_add(ioctx, "uuid1", "cluster1", "client"));
+ std::string uuid1;
+ ASSERT_EQ(-EINVAL, rbd.mirror_peer_add(ioctx, &uuid1, "cluster1", "client"));
rbd_mirror_mode_t mirror_mode;
ASSERT_EQ(0, rbd.mirror_mode_get(ioctx, &mirror_mode));
ASSERT_EQ(0, rbd.mirror_mode_get(ioctx, &mirror_mode));
ASSERT_EQ(RBD_MIRROR_MODE_POOL, mirror_mode);
- ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, "uuid1", "cluster1", "client"));
- ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, "uuid2", "cluster2", "admin"));
- ASSERT_EQ(-EEXIST, rbd.mirror_peer_add(ioctx, "uuid2", "cluster3", "foo"));
- ASSERT_EQ(-EEXIST, rbd.mirror_peer_add(ioctx, "uuid3", "cluster1", "foo"));
- ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, "uuid3", "cluster3", "admin"));
+ std::string uuid2;
+ std::string uuid3;
+ ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, &uuid1, "cluster1", "client"));
+ ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, &uuid2, "cluster2", "admin"));
+ ASSERT_EQ(-EEXIST, rbd.mirror_peer_add(ioctx, &uuid3, "cluster1", "foo"));
+ ASSERT_EQ(0, rbd.mirror_peer_add(ioctx, &uuid3, "cluster3", "admin"));
ASSERT_EQ(0, rbd.mirror_peer_list(ioctx, &peers));
+ auto sort_peers = [](const librbd::mirror_peer_t &lhs,
+ const librbd::mirror_peer_t &rhs) {
+ return lhs.uuid < rhs.uuid;
+ };
expected_peers = {
- {"uuid1", "cluster1", "client"},
- {"uuid2", "cluster2", "admin"},
- {"uuid3", "cluster3", "admin"}};
+ {uuid1, "cluster1", "client"},
+ {uuid2, "cluster2", "admin"},
+ {uuid3, "cluster3", "admin"}};
+ std::sort(expected_peers.begin(), expected_peers.end(), sort_peers);
ASSERT_EQ(expected_peers, peers);
ASSERT_EQ(0, rbd.mirror_peer_remove(ioctx, "uuid4"));
- ASSERT_EQ(0, rbd.mirror_peer_remove(ioctx, "uuid2"));
+ ASSERT_EQ(0, rbd.mirror_peer_remove(ioctx, uuid2));
ASSERT_EQ(-ENOENT, rbd.mirror_peer_set_client(ioctx, "uuid4", "new client"));
- ASSERT_EQ(0, rbd.mirror_peer_set_client(ioctx, "uuid1", "new client"));
+ ASSERT_EQ(0, rbd.mirror_peer_set_client(ioctx, uuid1, "new client"));
ASSERT_EQ(-ENOENT, rbd.mirror_peer_set_cluster(ioctx, "uuid4",
"new cluster"));
- ASSERT_EQ(0, rbd.mirror_peer_set_cluster(ioctx, "uuid3", "new cluster"));
+ ASSERT_EQ(0, rbd.mirror_peer_set_cluster(ioctx, uuid3, "new cluster"));
ASSERT_EQ(0, rbd.mirror_peer_list(ioctx, &peers));
expected_peers = {
- {"uuid1", "cluster1", "new client"},
- {"uuid3", "new cluster", "admin"}};
+ {uuid1, "cluster1", "new client"},
+ {uuid3, "new cluster", "admin"}};
+ std::sort(expected_peers.begin(), expected_peers.end(), sort_peers);
ASSERT_EQ(expected_peers, peers);
ASSERT_EQ(-EBUSY, rbd.mirror_mode_set(ioctx, RBD_MIRROR_MODE_DISABLED));
}
}
- void create_pool(bool enable_mirroring, const peer_t &peer, string *name=nullptr) {
+ void create_pool(bool enable_mirroring, const peer_t &peer,
+ string *uuid = nullptr, string *name=nullptr) {
string pool_name = get_temp_pool_name();
ASSERT_EQ("", create_one_pool_pp(pool_name, *m_cluster));
int64_t pool_id = m_cluster->pool_lookup(pool_name.c_str());
librados::IoCtx ioctx;
ASSERT_EQ(0, m_cluster->ioctx_create2(pool_id, ioctx));
ASSERT_EQ(0, librbd::mirror_mode_set(ioctx, RBD_MIRROR_MODE_POOL));
- ASSERT_EQ(0, librbd::mirror_peer_add(ioctx, peer.cluster_uuid,
+
+ std::string gen_uuid;
+ ASSERT_EQ(0, librbd::mirror_peer_add(ioctx,
+ uuid != nullptr ? uuid : &gen_uuid,
peer.cluster_name,
peer.client_name));
m_peer_configs[peer].insert(pool_id);
}
TEST_F(TestClusterWatcher, ReplicatedPools) {
- string uuid1 = "00000000-0000-0000-0000-000000000001";
- string uuid2 = "20000000-2222-2222-2222-000000000002";
- peer_t site1(uuid1, "site1", "mirror1");
- peer_t site2(uuid2, "site2", "mirror2");
+ peer_t site1("", "site1", "mirror1");
+ peer_t site2("", "site2", "mirror2");
string first_pool, last_pool;
check_peers();
- create_pool(true, site1, &first_pool);
+ create_pool(true, site1, &site1.uuid, &first_pool);
check_peers();
create_pool(false, peer_t());
check_peers();
check_peers();
create_pool(false, peer_t());
check_peers();
- create_pool(true, site2);
+ create_pool(true, site2, &site2.uuid);
check_peers();
- create_pool(true, site2);
+ create_pool(true, site2, &site2.uuid);
check_peers();
- create_pool(true, site2, &last_pool);
+ create_pool(true, site2, &site2.uuid, &last_pool);
check_peers();
delete_pool(first_pool, site1);
check_peers();
}
TEST_F(TestClusterWatcher, CachePools) {
- peer_t site1("11111111-1111-1111-1111-111111111111", "site1", "mirror1");
+ peer_t site1("", "site1", "mirror1");
string base1, base2, cache1, cache2;
- create_pool(true, site1, &base1);
+ create_pool(true, site1, &site1.uuid, &base1);
check_peers();
create_cache_pool(base1, &cache1);
} BOOST_SCOPE_EXIT_END;
check_peers();
- create_pool(false, peer_t(), &base2);
+ create_pool(false, peer_t(), nullptr, &base2);
create_cache_pool(base2, &cache2);
BOOST_SCOPE_EXIT( base2, cache2, this_ ) {
this_->remove_cache_pool(base2, cache2);
librados::IoCtx ioctx;
ASSERT_EQ(0, m_cluster->ioctx_create2(pool_id, ioctx));
ASSERT_EQ(0, librbd::mirror_mode_set(ioctx, RBD_MIRROR_MODE_POOL));
- ASSERT_EQ(0, librbd::mirror_peer_add(ioctx, peer.cluster_uuid,
+ std::string uuid;
+ ASSERT_EQ(0, librbd::mirror_peer_add(ioctx, &uuid,
peer.cluster_name,
peer.client_name));
}
namespace {
-int init_remote(const std::string &config_path, const std::string &client_name,
- const std::string &cluster_name, const std::string &pool_name,
- librados::Rados *rados, librados::IoCtx *io_ctx) {
- int r = rados->init2(client_name.c_str(), cluster_name.c_str(), 0);
- if (r < 0) {
- std::cerr << "rbd: couldn't initialize remote rados!" << std::endl;
- return r;
- }
-
- r = rados->conf_read_file(config_path.empty() ? nullptr :
- config_path.c_str());
- if (r < 0) {
- std::cerr << "rbd: couldn't read remote configuration" << std::endl;
- return r;
- }
-
- r = rados->connect();
- if (r < 0) {
- std::cerr << "rbd: couldn't connect to the remote cluster!" << std::endl;
- return r;
- }
-
- if (io_ctx != nullptr) {
- r = utils::init_io_ctx(*rados, pool_name, io_ctx);
- if (r < 0) {
- return r;
- }
- }
- return 0;
-}
-
int validate_uuid(const std::string &uuid) {
boost::regex pattern("^[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}$",
boost::regex::icase);
return 0;
}
-void add_cluster_uuid_option(po::options_description *positional) {
+void add_uuid_option(po::options_description *positional) {
positional->add_options()
- ("cluster-uuid", po::value<std::string>(), "cluster UUID");
+ ("uuid", po::value<std::string>(), "peer uuid");
}
-int get_cluster_uuid(const po::variables_map &vm, size_t arg_index,
- std::string *cluster_uuid) {
- *cluster_uuid = utils::get_positional_argument(vm, arg_index);
- if (cluster_uuid->empty()) {
- std::cerr << "rbd: must specify cluster uuid" << std::endl;
+int get_uuid(const po::variables_map &vm, size_t arg_index,
+ std::string *uuid) {
+ *uuid = utils::get_positional_argument(vm, arg_index);
+ if (uuid->empty()) {
+ std::cerr << "rbd: must specify peer uuid" << std::endl;
return -EINVAL;
}
- return validate_uuid(*cluster_uuid);
+ return validate_uuid(*uuid);
}
int get_remote_cluster_spec(const po::variables_map &vm,
const std::string &spec,
std::string *remote_client_name,
- std::string *remote_cluster,
- std::string *remote_cluster_uuid) {
+ std::string *remote_cluster) {
if (vm.count("remote-client-name")) {
*remote_client_name = vm["remote-client-name"].as<std::string>();
}
if (vm.count("remote-cluster")) {
*remote_cluster = vm["remote-cluster"].as<std::string>();
}
- if (vm.count("remote-cluster-uuid")) {
- *remote_cluster_uuid = vm["remote-cluster-uuid"].as<std::string>();
- int r = validate_uuid(*remote_cluster_uuid);
- if (r < 0) {
- return r;
- }
- }
if (!spec.empty()) {
boost::regex pattern("^(?:(client\\.[^@]+)@)?([^/@]+)$");
formatter->open_array_section("peers");
for (auto &peer : peers) {
formatter->open_object_section("peer");
- formatter->dump_string("cluster_uuid", peer.cluster_uuid);
+ formatter->dump_string("uuid", peer.uuid);
formatter->dump_string("cluster_name", peer.cluster_name);
formatter->dump_string("client_name", peer.client_name);
formatter->close_section();
tbl.define_column("CLIENT", TextTable::LEFT, TextTable::LEFT);
for (auto &peer : peers) {
tbl << " "
- << peer.cluster_uuid
+ << peer.uuid
<< peer.cluster_name
<< peer.client_name
<< TextTable::endrow;
"(example: [<client name>@]<cluster name>");
options->add_options()
("remote-client-name", po::value<std::string>(), "remote client name")
- ("remote-cluster", po::value<std::string>(), "remote cluster name")
- ("remote-cluster-uuid", po::value<std::string>(), "remote cluster uuid");
+ ("remote-cluster", po::value<std::string>(), "remote cluster name");
}
int execute_peer_add(const po::variables_map &vm) {
std::string remote_client_name = g_ceph_context->_conf->name.to_str();
std::string remote_cluster;
- std::string remote_cluster_uuid;
int r = get_remote_cluster_spec(
vm, utils::get_positional_argument(vm, arg_index),
- &remote_client_name, &remote_cluster, &remote_cluster_uuid);
+ &remote_client_name, &remote_cluster);
if (r < 0) {
return r;
}
return r;
}
- if (remote_cluster_uuid.empty()) {
- librados::Rados remote_rados;
- librados::IoCtx remote_io_ctx;
- r = init_remote(config_path, remote_client_name, remote_cluster,
- pool_name, &remote_rados, &remote_io_ctx);
- if (r < 0) {
- return r;
- }
-
- r = remote_rados.cluster_fsid(&remote_cluster_uuid);
- if (r < 0) {
- std::cerr << "rbd: error retrieving remote cluster id" << std::endl;
- return r;
- }
- }
-
librbd::RBD rbd;
- r = rbd.mirror_peer_add(io_ctx, remote_cluster_uuid, remote_cluster,
- remote_client_name);
+ std::string uuid;
+ r = rbd.mirror_peer_add(io_ctx, &uuid, remote_cluster, remote_client_name);
if (r < 0) {
std::cerr << "rbd: error adding mirror peer" << std::endl;
return r;
}
+
+ std::cout << uuid << std::endl;
return 0;
}
void get_peer_remove_arguments(po::options_description *positional,
po::options_description *options) {
at::add_pool_options(positional, options);
- add_cluster_uuid_option(positional);
+ add_uuid_option(positional);
}
int execute_peer_remove(const po::variables_map &vm) {
size_t arg_index = 0;
std::string pool_name = utils::get_pool_name(vm, &arg_index);
- std::string cluster_uuid;
- int r = get_cluster_uuid(vm, arg_index, &cluster_uuid);
+ std::string uuid;
+ int r = get_uuid(vm, arg_index, &uuid);
if (r < 0) {
return r;
}
}
librbd::RBD rbd;
- r = rbd.mirror_peer_remove(io_ctx, cluster_uuid);
+ r = rbd.mirror_peer_remove(io_ctx, uuid);
if (r < 0) {
std::cerr << "rbd: error removing mirror peer" << std::endl;
return r;
void get_peer_set_arguments(po::options_description *positional,
po::options_description *options) {
at::add_pool_options(positional, options);
- add_cluster_uuid_option(positional);
+ add_uuid_option(positional);
positional->add_options()
("key", "peer parameter [client or cluster]")
("value", "new client or cluster name");
size_t arg_index = 0;
std::string pool_name = utils::get_pool_name(vm, &arg_index);
- std::string cluster_uuid;
- int r = get_cluster_uuid(vm, arg_index++, &cluster_uuid);
+ std::string uuid;
+ int r = get_uuid(vm, arg_index++, &uuid);
if (r < 0) {
return r;
}
librbd::RBD rbd;
if (key == "client") {
- r = rbd.mirror_peer_set_client(io_ctx, cluster_uuid.c_str(), value.c_str());
+ r = rbd.mirror_peer_set_client(io_ctx, uuid.c_str(), value.c_str());
} else {
- r = rbd.mirror_peer_set_cluster(io_ctx, cluster_uuid.c_str(),
- value.c_str());
+ r = rbd.mirror_peer_set_cluster(io_ctx, uuid.c_str(), value.c_str());
}
if (r < 0) {
return r;
std::cout << "Mode: " << mirror_mode_desc << std::endl;
}
- format_mirror_peers(config_path, formatter, mirror_peers);
+ if (mirror_mode != RBD_MIRROR_MODE_DISABLED) {
+ format_mirror_peers(config_path, formatter, mirror_peers);
+ }
if (formatter != nullptr) {
formatter->close_section();
formatter->flush(std::cout);
return r;
}
- string cluster_uuid;
- r = m_remote->cluster_fsid(&cluster_uuid);
- if (r < 0) {
- derr << "error reading cluster uuid from remote cluster " << m_peer
- << " : " << cpp_strerror(r) << dendl;
- return r;
- }
-
- if (cluster_uuid != m_peer.cluster_uuid) {
- derr << "configured cluster uuid does not match actual cluster uuid. "
- << "expected: " << m_peer.cluster_uuid
- << " observed: " << cluster_uuid << dendl;
- return -EINVAL;
- }
-
dout(20) << __func__ << "connected to " << m_peer << dendl;
// TODO: make interval configurable
std::ostream& operator<<(std::ostream& lhs, const rbd::mirror::peer_t &peer)
{
- return lhs << "name: " << peer.cluster_name
- << " uuid: " << peer.cluster_uuid
+ return lhs << "uuid: " << peer.uuid
+ << " cluster: " << peer.cluster_name
<< " client: " << peer.client_name;
}
peer_t() = default;
peer_t(const std::string &uuid, const std::string &cluster_name,
const std::string &client_name)
- : cluster_uuid(uuid), cluster_name(cluster_name), client_name(client_name)
+ : uuid(uuid), cluster_name(cluster_name), client_name(client_name)
{
}
peer_t(const librbd::mirror_peer_t &peer) :
- cluster_uuid(peer.cluster_uuid),
+ uuid(peer.uuid),
cluster_name(peer.cluster_name),
client_name(peer.client_name)
{
}
- std::string cluster_uuid;
+ std::string uuid;
std::string cluster_name;
std::string client_name;
bool operator<(const peer_t &rhs) const {
- return this->cluster_uuid < rhs.cluster_uuid;
+ return this->uuid < rhs.uuid;
}
bool operator()(const peer_t &lhs, const peer_t &rhs) const {
- return lhs.cluster_uuid < rhs.cluster_uuid;
+ return lhs.uuid < rhs.uuid;
}
bool operator==(const peer_t &rhs) const {
- return cluster_uuid == rhs.cluster_uuid;
+ return uuid == rhs.uuid;
}
};