return (*opts_)->empty();
}
+ int list_images_v2(IoCtx& io_ctx, map<string, string> &images) {
+ CephContext *cct = (CephContext *)io_ctx.cct();
+ ldout(cct, 20) << "list_images_v2 " << &io_ctx << dendl;
+
+ // new format images are accessed by class methods
+ int r;
+ int max_read = 1024;
+ string last_read = "";
+ do {
+ map<string, string> images_page;
+ r = cls_client::dir_list(&io_ctx, RBD_DIRECTORY,
+ last_read, max_read, &images_page);
+ if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "error listing image in directory: "
+ << cpp_strerror(r) << dendl;
+ return r;
+ } else if (r == -ENOENT) {
+ break;
+ }
+ for (map<string, string>::const_iterator it = images_page.begin();
+ it != images_page.end(); ++it) {
+ images.insert(*it);
+ }
+ if (!images_page.empty()) {
+ last_read = images_page.rbegin()->first;
+ }
+ r = images_page.size();
+ } while (r == max_read);
+
+ return 0;
+ }
+
int list(IoCtx& io_ctx, vector<string>& names)
{
CephContext *cct = (CephContext *)io_ctx.cct();
}
}
- // new format images are accessed by class methods
- int max_read = 1024;
- string last_read = "";
- do {
- map<string, string> images;
- r = cls_client::dir_list(&io_ctx, RBD_DIRECTORY,
- last_read, max_read, &images);
- if (r < 0) {
- lderr(cct) << "error listing image in directory: "
- << cpp_strerror(r) << dendl;
- return r;
- }
- for (map<string, string>::const_iterator it = images.begin();
- it != images.end(); ++it) {
- names.push_back(it->first);
- }
- if (!images.empty()) {
- last_read = images.rbegin()->first;
- }
- r = images.size();
- } while (r == max_read);
+ map<string, string> images;
+ r = list_images_v2(io_ctx, images);
+ if (r < 0) {
+ lderr(cct) << "error listing v2 images: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+ for (const auto& img_pair : images) {
+ names.push_back(img_pair.first);
+ }
return 0;
}
}
}
+ if (current_mirror_mode != cls::rbd::MIRROR_MODE_IMAGE) {
+ r = cls_client::mirror_mode_set(&io_ctx, cls::rbd::MIRROR_MODE_IMAGE);
+ if (r < 0) {
+ lderr(cct) << "Failed to set mirror mode to image: "
+ << cpp_strerror(r) << dendl;
+ return r;
+ }
+ }
+
+ if (next_mirror_mode == cls::rbd::MIRROR_MODE_IMAGE) {
+ return 0;
+ }
+
+ struct rollback_state_t {
+ IoCtx *io_ctx;
+ bool do_rollback;
+ cls::rbd::MirrorMode mirror_mode;
+ bool enable;
+ std::vector<std::pair<ImageCtx *, bool> > img_ctxs;
+
+ rollback_state_t(IoCtx *io_ctx, cls::rbd::MirrorMode mirror_mode, bool enable) :
+ io_ctx(io_ctx),
+ do_rollback(true),
+ mirror_mode(mirror_mode),
+ enable(enable) {
+ }
+ ~rollback_state_t() {
+ CephContext *cct = reinterpret_cast<CephContext *>(io_ctx->cct());
+ if (do_rollback && mirror_mode != cls::rbd::MIRROR_MODE_IMAGE) {
+ int r = cls_client::mirror_mode_set(io_ctx, mirror_mode);
+ if (r < 0) {
+ lderr(cct) << "Failed to rollback mirror mode: " << cpp_strerror(r)
+ << dendl;
+ }
+ }
+ for (const auto& pair : img_ctxs) {
+ if (do_rollback && pair.second) {
+ int r = enable ? mirror_image_disable(pair.first, false) :
+ mirror_image_enable(pair.first);
+ if (r < 0) {
+ lderr(cct) << "Failed to rollback mirroring state for image id "
+ << pair.first->id << ": " << cpp_strerror(r) << dendl;
+ }
+ }
+
+ int r = pair.first->state->close();
+ if (r < 0) {
+ lderr(cct) << "error closing image " << pair.first->id << ": "
+ << cpp_strerror(r) << dendl;
+ }
+ }
+ }
+ } rb_state(&io_ctx, current_mirror_mode,
+ next_mirror_mode == cls::rbd::MIRROR_MODE_POOL);
+
+
+ if (next_mirror_mode == cls::rbd::MIRROR_MODE_POOL) {
+
+ map<string, string> images;
+ r = list_images_v2(io_ctx, images);
+ if (r < 0) {
+ lderr(cct) << "Failed listing images: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ for (const auto& img_pair : images) {
+ uint64_t features;
+ r = cls_client::get_features(&io_ctx, util::header_name(img_pair.second),
+ CEPH_NOSNAP, &features);
+ if (r < 0) {
+ lderr(cct) << "error getting features for image " << img_pair.first
+ << ": " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ if ((features & RBD_FEATURE_JOURNALING) != 0) {
+ ImageCtx *img_ctx = new ImageCtx("", img_pair.second, nullptr,
+ io_ctx, false);
+ r = img_ctx->state->open();
+ if (r < 0) {
+ lderr(cct) << "error opening image "<< img_pair.first << ": "
+ << cpp_strerror(r) << dendl;
+ delete img_ctx;
+ return r;
+ }
+
+ r = mirror_image_enable(img_ctx);
+ if (r < 0) {
+ lderr(cct) << "error enabling mirroring for image "
+ << img_pair.first << ": " << cpp_strerror(r) << dendl;
+ rb_state.img_ctxs.push_back(std::make_pair(img_ctx, false));
+ return r;
+ }
+
+ rb_state.img_ctxs.push_back(std::make_pair(img_ctx, true));
+ }
+ }
+ }
+
+ rb_state.do_rollback = false;
+
r = cls_client::mirror_mode_set(&io_ctx, next_mirror_mode);
if (r < 0) {
lderr(cct) << "Failed to set mirror mode: " << cpp_strerror(r) << dendl;
return r;
}
+
return 0;
}