int r;
do {
std::map<std::string, std::string> mirror_images;
- r = cls_client::mirror_image_list(&io_ctx, last_read, max_read,
- &mirror_images);
- if (r < 0) {
+ r = cls_client::mirror_image_list(&io_ctx, last_read, max_read,
+ &mirror_images);
+ if (r < 0 && r != -ENOENT) {
lderr(cct) << "error listing mirrored image directory: "
- << cpp_strerror(r) << dendl;
+ << cpp_strerror(r) << dendl;
return r;
}
for (auto it = mirror_images.begin(); it != mirror_images.end(); ++it) {
std::map<cls::rbd::MirrorImageStatusState, int> states_;
int r = cls_client::mirror_image_status_get_summary(&io_ctx, &states_);
- if (r < 0) {
+ if (r < 0 && r != -ENOENT) {
lderr(cct) << "Failed to get mirror status summary: "
<< cpp_strerror(r) << dendl;
return r;
namespace at = argument_types;
namespace po = boost::program_options;
+namespace {
+
+int validate_mirroring_enabled(librbd::Image& image) {
+ librbd::mirror_image_info_t mirror_image;
+ int r = image.mirror_image_get_info(&mirror_image, sizeof(mirror_image));
+ if (r < 0) {
+ std::cerr << "rbd: failed to retrieve mirror mode: "
+ << cpp_strerror(r) << std::endl;
+ return r;
+ }
+
+ if (mirror_image.state != RBD_MIRROR_IMAGE_ENABLED) {
+ std::cerr << "rbd: mirroring not enabled on the image" << std::endl;
+ return -EINVAL;
+ }
+ return 0;
+}
+
+} // anonymous namespace
void get_arguments(po::options_description *positional,
po::options_description *options) {
return r;
}
+ r = validate_mirroring_enabled(image);
+ if (r < 0) {
+ return r;
+ }
+
r = image.mirror_image_promote(force);
if (r < 0) {
std::cerr << "rbd: error promoting image to primary" << std::endl;
return r;
}
+ r = validate_mirroring_enabled(image);
+ if (r < 0) {
+ return r;
+ }
+
r = image.mirror_image_demote();
if (r < 0) {
std::cerr << "rbd: error demoting image to non-primary" << std::endl;
return r;
}
+ r = validate_mirroring_enabled(image);
+ if (r < 0) {
+ return r;
+ }
+
r = image.mirror_image_resync();
if (r < 0) {
std::cerr << "rbd: error flagging image resync" << std::endl;
return r;
}
+ r = validate_mirroring_enabled(image);
+ if (r < 0) {
+ return r;
+ }
+
librbd::mirror_image_status_t status;
r = image.mirror_image_get_status(&status, sizeof(status));
if (r < 0) {
namespace {
+int validate_mirroring_enabled(librados::IoCtx& io_ctx) {
+ librbd::RBD rbd;
+ rbd_mirror_mode_t mirror_mode;
+ int r = rbd.mirror_mode_get(io_ctx, &mirror_mode);
+ if (r < 0) {
+ std::cerr << "rbd: failed to retrieve mirror mode: "
+ << cpp_strerror(r) << std::endl;
+ return r;
+ }
+
+ if (mirror_mode == RBD_MIRROR_MODE_DISABLED) {
+ std::cerr << "rbd: mirroring not enabled on the pool" << std::endl;
+ return -EINVAL;
+ }
+ 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 r;
}
+ r = validate_mirroring_enabled(io_ctx);
+ if (r < 0) {
+ return r;
+ }
+
// TODO: temporary restriction to prevent adding multiple peers
// until rbd-mirror daemon can properly handle the scenario
librbd::RBD rbd;
return r;
}
+ r = validate_mirroring_enabled(io_ctx);
+ if (r < 0) {
+ return r;
+ }
+
librbd::RBD rbd;
r = rbd.mirror_peer_remove(io_ctx, uuid);
if (r < 0) {
return r;
}
+ r = validate_mirroring_enabled(io_ctx);
+ if (r < 0) {
+ return r;
+ }
+
librbd::RBD rbd;
if (key == "client") {
r = rbd.mirror_peer_set_client(io_ctx, uuid.c_str(), value.c_str());
return r;
}
+ r = validate_mirroring_enabled(io_ctx);
+ if (r < 0) {
+ return r;
+ }
+
librbd::RBD rbd;
std::map<librbd::mirror_image_status_state_t, int> states;
}
for (auto it = mirror_images.begin(); it != mirror_images.end(); ++it) {
librbd::mirror_image_status_t &status = it->second;
+ if (status.info.global_id.empty()) {
+ continue;
+ }
+
const std::string &image_name = status.name;
std::string &global_image_id = status.info.global_id;
std::string state = utils::mirror_image_status_state(status);