cls::rbd:: methods to store/retrieve mirroring status

Signed-off-by: Mykola Golub <mgolub@mirantis.com>
This commit is contained in:
Mykola Golub 2016-04-05 14:24:07 +03:00
parent 44a31d2b77
commit 17dd40df4f
5 changed files with 801 additions and 0 deletions

View File

@ -40,6 +40,7 @@
#include "common/bit_vector.hpp"
#include "common/errno.h"
#include "objclass/objclass.h"
#include "osd/osd_types.h"
#include "include/rbd_types.h"
#include "include/rbd/object_map_types.h"
@ -125,6 +126,12 @@ cls_method_handle_t h_mirror_image_get_image_id;
cls_method_handle_t h_mirror_image_get;
cls_method_handle_t h_mirror_image_set;
cls_method_handle_t h_mirror_image_remove;
cls_method_handle_t h_mirror_image_status_set;
cls_method_handle_t h_mirror_image_status_remove;
cls_method_handle_t h_mirror_image_status_get;
cls_method_handle_t h_mirror_image_status_list;
cls_method_handle_t h_mirror_image_status_get_summary;
cls_method_handle_t h_mirror_image_status_remove_down;
#define RBD_MAX_KEYS_READ 64
#define RBD_SNAP_KEY_PREFIX "snapshot_"
@ -2965,6 +2972,7 @@ static const std::string MODE("mirror_mode");
static const std::string PEER_KEY_PREFIX("mirror_peer_");
static const std::string IMAGE_KEY_PREFIX("image_");
static const std::string GLOBAL_KEY_PREFIX("global_");
static const std::string STATUS_GLOBAL_KEY_PREFIX("status_global_");
std::string peer_key(const std::string &uuid) {
return PEER_KEY_PREFIX + uuid;
@ -2978,6 +2986,10 @@ std::string global_key(const string &global_id) {
return GLOBAL_KEY_PREFIX + global_id;
}
std::string status_global_key(const string &global_id) {
return STATUS_GLOBAL_KEY_PREFIX + global_id;
}
int uuid_get(cls_method_context_t hctx, std::string *mirror_uuid) {
bufferlist mirror_uuid_bl;
int r = cls_cxx_map_get_val(hctx, mirror::UUID, &mirror_uuid_bl);
@ -3162,6 +3174,296 @@ int image_remove(cls_method_context_t hctx, const string &image_id) {
return 0;
}
struct MirrorImageStatusOnDisk : cls::rbd::MirrorImageStatus {
entity_inst_t origin;
MirrorImageStatusOnDisk() {
}
MirrorImageStatusOnDisk(const cls::rbd::MirrorImageStatus &status) :
cls::rbd::MirrorImageStatus(status) {
}
void encode_meta(bufferlist &bl) const {
ENCODE_START(1, 1, bl);
::encode(origin, bl);
ENCODE_FINISH(bl);
}
void encode(bufferlist &bl) const {
encode_meta(bl);
cls::rbd::MirrorImageStatus::encode(bl);
}
void decode_meta(bufferlist::iterator &it) {
DECODE_START(1, it);
::decode(origin, it);
DECODE_FINISH(it);
}
void decode(bufferlist::iterator &it) {
decode_meta(it);
cls::rbd::MirrorImageStatus::decode(it);
}
};
WRITE_CLASS_ENCODER(MirrorImageStatusOnDisk)
int image_status_set(cls_method_context_t hctx, const string &global_image_id,
const cls::rbd::MirrorImageStatus &status) {
MirrorImageStatusOnDisk ondisk_status(status);
ondisk_status.up = false;
ondisk_status.last_update = ceph_clock_now(g_ceph_context);
int r = cls_get_request_origin(hctx, &ondisk_status.origin);
assert(r == 0);
bufferlist bl;
encode(ondisk_status, bl);
r = cls_cxx_map_set_val(hctx, status_global_key(global_image_id), &bl);
if (r < 0) {
CLS_ERR("error setting status for mirrored image, global id '%s': %s",
global_image_id.c_str(), cpp_strerror(r).c_str());
return r;
}
return 0;
}
int image_status_remove(cls_method_context_t hctx,
const string &global_image_id) {
int r = cls_cxx_map_remove_key(hctx, status_global_key(global_image_id));
if (r < 0) {
CLS_ERR("error removing status for mirrored image, global id '%s': %s",
global_image_id.c_str(), cpp_strerror(r).c_str());
return r;
}
return 0;
}
int image_status_get(cls_method_context_t hctx, const string &global_image_id,
cls::rbd::MirrorImageStatus *status) {
bufferlist bl;
int r = cls_cxx_map_get_val(hctx, status_global_key(global_image_id), &bl);
if (r < 0) {
if (r != -ENOENT) {
CLS_ERR("error reading status for mirrored image, global id '%s': '%s'",
global_image_id.c_str(), cpp_strerror(r).c_str());
}
return r;
}
MirrorImageStatusOnDisk ondisk_status;
try {
bufferlist::iterator it = bl.begin();
decode(ondisk_status, it);
} catch (const buffer::error &err) {
CLS_ERR("could not decode status for mirrored image, global id '%s'",
global_image_id.c_str());
return -EIO;
}
obj_list_watch_response_t watchers;
r = cls_cxx_list_watchers(hctx, &watchers);
if (r < 0 && r != -ENOENT) {
CLS_ERR("error listing watchers: '%s'", cpp_strerror(r).c_str());
return r;
}
*status = static_cast<cls::rbd::MirrorImageStatus>(ondisk_status);
status->up = false;
for (auto &w : watchers.entries) {
if (w.name == ondisk_status.origin.name &&
w.addr == ondisk_status.origin.addr) {
status->up = true;
break;
}
}
return 0;
}
int image_status_list(cls_method_context_t hctx,
const std::string &start_after, uint64_t max_return,
map<std::string, cls::rbd::MirrorImage> *mirror_images,
map<std::string, cls::rbd::MirrorImageStatus> *mirror_statuses) {
std::string last_read = image_key(start_after);
int max_read = RBD_MAX_KEYS_READ;
int r = max_read;
while (r == max_read && mirror_images->size() < max_return) {
std::map<std::string, bufferlist> vals;
CLS_LOG(20, "last_read = '%s'", last_read.c_str());
r = cls_cxx_map_get_vals(hctx, last_read, IMAGE_KEY_PREFIX, max_read,
&vals);
if (r < 0) {
CLS_ERR("error reading mirror image directory by name: %s",
cpp_strerror(r).c_str());
return r;
}
for (auto it = vals.begin(); it != vals.end() &&
mirror_images->size() < max_return; ++it) {
const std::string &image_id = it->first.substr(IMAGE_KEY_PREFIX.size());
cls::rbd::MirrorImage mirror_image;
bufferlist::iterator iter = it->second.begin();
try {
::decode(mirror_image, iter);
} catch (const buffer::error &err) {
CLS_ERR("could not decode mirror image payload of image '%s'",
image_id.c_str());
return -EIO;
}
(*mirror_images)[image_id] = mirror_image;
cls::rbd::MirrorImageStatus status;
r = image_status_get(hctx, mirror_image.global_image_id, &status);
if (r < 0) {
continue;
}
(*mirror_statuses)[image_id] = status;
}
if (!vals.empty()) {
last_read = image_key(mirror_images->rbegin()->first);
}
}
return 0;
}
int image_status_get_summary(cls_method_context_t hctx,
std::map<cls::rbd::MirrorImageStatusState, int> *states) {
obj_list_watch_response_t watchers_;
int r = cls_cxx_list_watchers(hctx, &watchers_);
if (r < 0) {
if (r != -ENOENT) {
CLS_ERR("error listing watchers: '%s'", cpp_strerror(r).c_str());
}
return r;
}
set<entity_inst_t> watchers;
for (auto &w : watchers_.entries) {
watchers.insert(entity_inst_t(w.name, w.addr));
}
states->clear();
string last_read = IMAGE_KEY_PREFIX;
int max_read = RBD_MAX_KEYS_READ;
r = max_read;
while (r == max_read) {
map<string, bufferlist> vals;
r = cls_cxx_map_get_vals(hctx, last_read, IMAGE_KEY_PREFIX,
max_read, &vals);
if (r < 0) {
CLS_ERR("error reading mirrored images: %s", cpp_strerror(r).c_str());
return r;
}
for (auto &list_it : vals) {
const string &key = list_it.first;
if (0 != key.compare(0, IMAGE_KEY_PREFIX.size(), IMAGE_KEY_PREFIX)) {
break;
}
cls::rbd::MirrorImage mirror_image;
bufferlist::iterator iter = list_it.second.begin();
try {
::decode(mirror_image, iter);
} catch (const buffer::error &err) {
CLS_ERR("could not decode mirror image payload for key '%s'",
key.c_str());
return -EIO;
}
cls::rbd::MirrorImageStatus status;
r = image_status_get(hctx, mirror_image.global_image_id, &status);
if (r < 0) {
// Ignore.
}
cls::rbd::MirrorImageStatusState state = status.up ? status.state :
cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN;
(*states)[state]++;
}
if (!vals.empty()) {
last_read = vals.rbegin()->first;
}
}
return 0;
}
int image_status_remove_down(cls_method_context_t hctx) {
obj_list_watch_response_t watchers_;
int r = cls_cxx_list_watchers(hctx, &watchers_);
if (r < 0) {
if (r != -ENOENT) {
CLS_ERR("error listing watchers: '%s'", cpp_strerror(r).c_str());
}
return r;
}
set<entity_inst_t> watchers;
for (auto &w : watchers_.entries) {
watchers.insert(entity_inst_t(w.name, w.addr));
}
string last_read = STATUS_GLOBAL_KEY_PREFIX;
int max_read = RBD_MAX_KEYS_READ;
r = max_read;
while (r == max_read) {
map<string, bufferlist> vals;
r = cls_cxx_map_get_vals(hctx, last_read, STATUS_GLOBAL_KEY_PREFIX,
max_read, &vals);
if (r < 0) {
CLS_ERR("error reading mirrored images: %s", cpp_strerror(r).c_str());
return r;
}
for (auto &list_it : vals) {
const string &key = list_it.first;
if (0 != key.compare(0, STATUS_GLOBAL_KEY_PREFIX.size(),
STATUS_GLOBAL_KEY_PREFIX)) {
break;
}
MirrorImageStatusOnDisk status;
try {
bufferlist::iterator it = list_it.second.begin();
status.decode_meta(it);
} catch (const buffer::error &err) {
CLS_ERR("could not decode status metadata for mirrored image '%s'",
key.c_str());
return -EIO;
}
if (watchers.find(status.origin) == watchers.end()) {
CLS_LOG(20, "removing stale status object for key %s",
key.c_str());
int r1 = cls_cxx_map_remove_key(hctx, key);
if (r1 < 0) {
CLS_ERR("error removing stale status for key '%s': %s",
key.c_str(), cpp_strerror(r1).c_str());
return r1;
}
}
}
if (!vals.empty()) {
last_read = vals.rbegin()->first;
}
}
return 0;
}
} // namespace mirror
/**
@ -3676,6 +3978,158 @@ int mirror_image_remove(cls_method_context_t hctx, bufferlist *in,
return 0;
}
/**
* Input:
* @param global_image_id (std::string)
* @param status (cls::rbd::MirrorImageStatus)
*
* Output:
* @returns 0 on success, negative error code on failure
*/
int mirror_image_status_set(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
string global_image_id;
cls::rbd::MirrorImageStatus status;
try {
bufferlist::iterator it = in->begin();
::decode(global_image_id, it);
::decode(status, it);
} catch (const buffer::error &err) {
return -EINVAL;
}
int r = mirror::image_status_set(hctx, global_image_id, status);
if (r < 0) {
return r;
}
return 0;
}
/**
* Input:
* @param global_image_id (std::string)
*
* Output:
* @returns 0 on success, negative error code on failure
*/
int mirror_image_status_remove(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
string global_image_id;
try {
bufferlist::iterator it = in->begin();
::decode(global_image_id, it);
} catch (const buffer::error &err) {
return -EINVAL;
}
int r = mirror::image_status_remove(hctx, global_image_id);
if (r < 0) {
return r;
}
return 0;
}
/**
* Input:
* @param global_image_id (std::string)
*
* Output:
* @param cls::rbd::MirrorImageStatus - metadata associated with the global_image_id
* @returns 0 on success, negative error code on failure
*/
int mirror_image_status_get(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
string global_image_id;
try {
bufferlist::iterator it = in->begin();
::decode(global_image_id, it);
} catch (const buffer::error &err) {
return -EINVAL;
}
cls::rbd::MirrorImageStatus status;
int r = mirror::image_status_get(hctx, global_image_id, &status);
if (r < 0) {
return r;
}
::encode(status, *out);
return 0;
}
/**
* Input:
* @param start_after which name to begin listing after
* (use the empty string to start at the beginning)
* @param max_return the maximum number of names to list
*
* Output:
* @param std::map<std::string, cls::rbd::MirrorImage>: image id to image map
* @param std::map<std::string, cls::rbd::MirrorImageStatus>: image it to status map
* @returns 0 on success, negative error code on failure
*/
int mirror_image_status_list(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
std::string start_after;
uint64_t max_return;
try {
bufferlist::iterator iter = in->begin();
::decode(start_after, iter);
::decode(max_return, iter);
} catch (const buffer::error &err) {
return -EINVAL;
}
map<std::string, cls::rbd::MirrorImage> images;
map<std::string, cls::rbd::MirrorImageStatus> statuses;
int r = mirror::image_status_list(hctx, start_after, max_return, &images,
&statuses);
if (r < 0) {
return r;
}
::encode(images, *out);
::encode(statuses, *out);
return 0;
}
/**
* Input:
* none
*
* Output:
* @param std::map<cls::rbd::MirrorImageStatusState, int>: states counts
* @returns 0 on success, negative error code on failure
*/
int mirror_image_status_get_summary(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
std::map<cls::rbd::MirrorImageStatusState, int> states;
int r = mirror::image_status_get_summary(hctx, &states);
if (r < 0) {
return r;
}
::encode(states, *out);
return 0;
}
/**
* Input:
* none
*
* Output:
* @returns 0 on success, negative error code on failure
*/
int mirror_image_status_remove_down(cls_method_context_t hctx, bufferlist *in,
bufferlist *out) {
int r = mirror::image_status_remove_down(hctx);
if (r < 0) {
return r;
}
return 0;
}
void __cls_init()
{
CLS_LOG(20, "Loaded rbd class!");
@ -3871,5 +4325,24 @@ void __cls_init()
cls_register_cxx_method(h_class, "mirror_image_remove",
CLS_METHOD_RD | CLS_METHOD_WR,
mirror_image_remove, &h_mirror_image_remove);
cls_register_cxx_method(h_class, "mirror_image_status_set",
CLS_METHOD_RD | CLS_METHOD_WR | CLS_METHOD_PROMOTE,
mirror_image_status_set, &h_mirror_image_status_set);
cls_register_cxx_method(h_class, "mirror_image_status_remove",
CLS_METHOD_RD | CLS_METHOD_WR,
mirror_image_status_remove,
&h_mirror_image_status_remove);
cls_register_cxx_method(h_class, "mirror_image_status_get", CLS_METHOD_RD,
mirror_image_status_get, &h_mirror_image_status_get);
cls_register_cxx_method(h_class, "mirror_image_status_list", CLS_METHOD_RD,
mirror_image_status_list,
&h_mirror_image_status_list);
cls_register_cxx_method(h_class, "mirror_image_status_get_summary",
CLS_METHOD_RD, mirror_image_status_get_summary,
&h_mirror_image_status_get_summary);
cls_register_cxx_method(h_class, "mirror_image_status_remove_down",
CLS_METHOD_RD | CLS_METHOD_WR,
mirror_image_status_remove_down,
&h_mirror_image_status_remove_down);
return;
}

View File

@ -1236,5 +1236,163 @@ namespace librbd {
return 0;
}
int mirror_image_status_set(librados::IoCtx *ioctx,
const std::string &global_image_id,
const cls::rbd::MirrorImageStatus &status) {
librados::ObjectWriteOperation op;
mirror_image_status_set(&op, global_image_id, status);
return ioctx->operate(RBD_MIRRORING, &op);
}
void mirror_image_status_set(librados::ObjectWriteOperation *op,
const std::string &global_image_id,
const cls::rbd::MirrorImageStatus &status) {
bufferlist bl;
::encode(global_image_id, bl);
::encode(status, bl);
op->exec("rbd", "mirror_image_status_set", bl);
}
int mirror_image_status_remove(librados::IoCtx *ioctx,
const std::string &global_image_id) {
librados::ObjectWriteOperation op;
mirror_image_status_remove(&op, global_image_id);
return ioctx->operate(RBD_MIRRORING, &op);
}
void mirror_image_status_remove(librados::ObjectWriteOperation *op,
const std::string &global_image_id) {
bufferlist bl;
::encode(global_image_id, bl);
op->exec("rbd", "mirror_image_status_remove", bl);
}
int mirror_image_status_get(librados::IoCtx *ioctx,
const std::string &global_image_id,
cls::rbd::MirrorImageStatus *status) {
librados::ObjectReadOperation op;
mirror_image_status_get_start(&op, global_image_id);
bufferlist out_bl;
int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
if (r < 0) {
return r;
}
bufferlist::iterator iter = out_bl.begin();
r = mirror_image_status_get_finish(&iter, status);
if (r < 0) {
return r;
}
return 0;
}
void mirror_image_status_get_start(librados::ObjectReadOperation *op,
const std::string &global_image_id) {
bufferlist bl;
::encode(global_image_id, bl);
op->exec("rbd", "mirror_image_status_get", bl);
}
int mirror_image_status_get_finish(bufferlist::iterator *iter,
cls::rbd::MirrorImageStatus *status) {
try {
::decode(*status, *iter);
} catch (const buffer::error &err) {
return -EBADMSG;
}
return 0;
}
int mirror_image_status_list(librados::IoCtx *ioctx,
const std::string &start, uint64_t max_return,
std::map<std::string, cls::rbd::MirrorImage> *images,
std::map<std::string, cls::rbd::MirrorImageStatus> *statuses) {
librados::ObjectReadOperation op;
mirror_image_status_list_start(&op, start, max_return);
bufferlist out_bl;
int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
if (r < 0) {
return r;
}
bufferlist::iterator iter = out_bl.begin();
r = mirror_image_status_list_finish(&iter, images, statuses);
if (r < 0) {
return r;
}
return 0;
}
void mirror_image_status_list_start(librados::ObjectReadOperation *op,
const std::string &start,
uint64_t max_return) {
bufferlist bl;
::encode(start, bl);
::encode(max_return, bl);
op->exec("rbd", "mirror_image_status_list", bl);
}
int mirror_image_status_list_finish(bufferlist::iterator *iter,
std::map<std::string, cls::rbd::MirrorImage> *images,
std::map<std::string, cls::rbd::MirrorImageStatus> *statuses) {
images->clear();
statuses->clear();
try {
::decode(*images, *iter);
::decode(*statuses, *iter);
} catch (const buffer::error &err) {
return -EBADMSG;
}
return 0;
}
int mirror_image_status_get_summary(librados::IoCtx *ioctx,
std::map<cls::rbd::MirrorImageStatusState, int> *states) {
librados::ObjectReadOperation op;
mirror_image_status_get_summary_start(&op);
bufferlist out_bl;
int r = ioctx->operate(RBD_MIRRORING, &op, &out_bl);
if (r < 0) {
return r;
}
bufferlist::iterator iter = out_bl.begin();
r = mirror_image_status_get_summary_finish(&iter, states);
if (r < 0) {
return r;
}
return 0;
}
void mirror_image_status_get_summary_start(
librados::ObjectReadOperation *op) {
bufferlist bl;
op->exec("rbd", "mirror_image_status_get_summary", bl);
}
int mirror_image_status_get_summary_finish(bufferlist::iterator *iter,
std::map<cls::rbd::MirrorImageStatusState, int> *states) {
try {
::decode(*states, *iter);
} catch (const buffer::error &err) {
return -EBADMSG;
}
return 0;
}
int mirror_image_status_remove_down(librados::IoCtx *ioctx) {
librados::ObjectWriteOperation op;
mirror_image_status_remove_down(&op);
return ioctx->operate(RBD_MIRRORING, &op);
}
void mirror_image_status_remove_down(librados::ObjectWriteOperation *op) {
bufferlist bl;
op->exec("rbd", "mirror_image_status_remove_down", bl);
}
} // namespace cls_client
} // namespace librbd

View File

@ -243,6 +243,40 @@ namespace librbd {
const cls::rbd::MirrorImage &mirror_image);
int mirror_image_remove(librados::IoCtx *ioctx,
const std::string &image_id);
int mirror_image_status_set(librados::IoCtx *ioctx,
const std::string &global_image_id,
const cls::rbd::MirrorImageStatus &status);
void mirror_image_status_set(librados::ObjectWriteOperation *op,
const std::string &global_image_id,
const cls::rbd::MirrorImageStatus &status);
int mirror_image_status_remove(librados::IoCtx *ioctx,
const std::string &global_image_id);
void mirror_image_status_remove(librados::ObjectWriteOperation *op,
const std::string &global_image_id);
int mirror_image_status_get(librados::IoCtx *ioctx,
const std::string &global_image_id,
cls::rbd::MirrorImageStatus *status);
void mirror_image_status_get_start(librados::ObjectReadOperation *op,
const std::string &global_image_id);
int mirror_image_status_get_finish(bufferlist::iterator *iter,
cls::rbd::MirrorImageStatus *status);
int mirror_image_status_list(librados::IoCtx *ioctx,
const std::string &start, uint64_t max_return,
std::map<std::string, cls::rbd::MirrorImage> *images,
std::map<std::string, cls::rbd::MirrorImageStatus> *statuses);
void mirror_image_status_list_start(librados::ObjectReadOperation *op,
const std::string &start,
uint64_t max_return);
int mirror_image_status_list_finish(bufferlist::iterator *iter,
std::map<std::string, cls::rbd::MirrorImage> *images,
std::map<std::string, cls::rbd::MirrorImageStatus> *statuses);
int mirror_image_status_get_summary(librados::IoCtx *ioctx,
std::map<cls::rbd::MirrorImageStatusState, int> *states);
void mirror_image_status_get_summary_start(librados::ObjectReadOperation *op);
int mirror_image_status_get_summary_finish(bufferlist::iterator *iter,
std::map<cls::rbd::MirrorImageStatusState, int> *states);
int mirror_image_status_remove_down(librados::IoCtx *ioctx);
void mirror_image_status_remove_down(librados::ObjectWriteOperation *op);
} // namespace cls_client
} // namespace librbd

View File

@ -105,6 +105,11 @@ bool MirrorImage::operator==(const MirrorImage &rhs) const {
return global_image_id == rhs.global_image_id && state == rhs.state;
}
bool MirrorImage::operator<(const MirrorImage &rhs) const {
return global_image_id < rhs.global_image_id ||
(global_image_id == rhs.global_image_id && state < rhs.state);
}
std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state) {
switch (mirror_state) {
case MIRROR_IMAGE_STATE_DISABLING:
@ -127,5 +132,84 @@ std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image) {
return os;
}
void MirrorImageStatus::encode(bufferlist &bl) const {
ENCODE_START(1, 1, bl);
::encode(state, bl);
::encode(description, bl);
::encode(last_update, bl);
::encode(up, bl);
ENCODE_FINISH(bl);
}
void MirrorImageStatus::decode(bufferlist::iterator &it) {
DECODE_START(1, it);
::decode(state, it);
::decode(description, it);
::decode(last_update, it);
::decode(up, it);
DECODE_FINISH(it);
}
void MirrorImageStatus::dump(Formatter *f) const {
f->dump_string("state", state_to_string());
f->dump_string("description", description);
f->dump_stream("last_update") << last_update;
}
std::string MirrorImageStatus::state_to_string() const {
std::stringstream ss;
ss << (up ? "up+" : "down+") << state;
return ss.str();
}
void MirrorImageStatus::generate_test_instances(
std::list<MirrorImageStatus*> &o) {
o.push_back(new MirrorImageStatus());
o.push_back(new MirrorImageStatus(MIRROR_IMAGE_STATUS_STATE_REPLAYING));
o.push_back(new MirrorImageStatus(MIRROR_IMAGE_STATUS_STATE_ERROR, "error"));
}
bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const {
return state == rhs.state && description == rhs.description && up == rhs.up;
}
std::ostream& operator<<(std::ostream& os, const MirrorImageStatusState& state) {
switch (state) {
case MIRROR_IMAGE_STATUS_STATE_UNKNOWN:
os << "unknown";
break;
case MIRROR_IMAGE_STATUS_STATE_ERROR:
os << "error";
break;
case MIRROR_IMAGE_STATUS_STATE_SYNCING:
os << "syncing";
break;
case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY:
os << "starting_replay";
break;
case MIRROR_IMAGE_STATUS_STATE_REPLAYING:
os << "replaying";
break;
case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY:
os << "stopping_replay";
break;
case MIRROR_IMAGE_STATUS_STATE_STOPPED:
os << "stopped";
break;
default:
os << "unknown (" << static_cast<uint32_t>(state) << ")";
break;
}
return os;
}
std::ostream& operator<<(std::ostream& os, const MirrorImageStatus& status) {
os << "["
<< "state=" << status.state_to_string() << ", "
<< "description=" << status.description << ", "
<< "last_update=" << status.last_update << "]";
return os;
}
} // namespace rbd
} // namespace cls

View File

@ -7,6 +7,7 @@
#include "include/int_types.h"
#include "include/buffer.h"
#include "include/encoding.h"
#include "include/utime.h"
#include <iosfwd>
#include <string>
@ -73,6 +74,7 @@ struct MirrorImage {
static void generate_test_instances(std::list<MirrorImage*> &o);
bool operator==(const MirrorImage &rhs) const;
bool operator<(const MirrorImage &rhs) const;
};
std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state);
@ -80,6 +82,56 @@ std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image);
WRITE_CLASS_ENCODER(MirrorImage);
enum MirrorImageStatusState {
MIRROR_IMAGE_STATUS_STATE_UNKNOWN = 0,
MIRROR_IMAGE_STATUS_STATE_ERROR = 1,
MIRROR_IMAGE_STATUS_STATE_SYNCING = 2,
MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY = 3,
MIRROR_IMAGE_STATUS_STATE_REPLAYING = 4,
MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY = 5,
MIRROR_IMAGE_STATUS_STATE_STOPPED = 6,
};
inline void encode(const MirrorImageStatusState &state, bufferlist& bl,
uint64_t features=0)
{
::encode(static_cast<uint8_t>(state), bl);
}
inline void decode(MirrorImageStatusState &state, bufferlist::iterator& it)
{
uint8_t int_state;
::decode(int_state, it);
state = static_cast<MirrorImageStatusState>(int_state);
}
struct MirrorImageStatus {
MirrorImageStatus() {}
MirrorImageStatus(MirrorImageStatusState state,
const std::string &description = "")
: state(state), description(description) {}
MirrorImageStatusState state = MIRROR_IMAGE_STATUS_STATE_UNKNOWN;
std::string description;
utime_t last_update;
bool up = false;
void encode(bufferlist &bl) const;
void decode(bufferlist::iterator &it);
void dump(Formatter *f) const;
std::string state_to_string() const;
static void generate_test_instances(std::list<MirrorImageStatus*> &o);
bool operator==(const MirrorImageStatus &rhs) const;
};
std::ostream& operator<<(std::ostream& os, const MirrorImageStatus& status);
std::ostream& operator<<(std::ostream& os, const MirrorImageStatusState& state);
WRITE_CLASS_ENCODER(MirrorImageStatus);
} // namespace rbd
} // namespace cls