#include "common/errno.h"
#include "common/Timer.h"
#include "common/WorkQueue.h"
+#include <boost/scope_exit.hpp>
#define dout_subsys ceph_subsys_rbd
#undef dout_prefix
template <typename I, typename J>
int open_journaler(I *image_ctx, J *journaler, bool *initialized,
- uint64_t *tag_class, journal::TagData *tag_data) {
+ journal::ImageClientMeta *client_meta,
+ journal::TagData *tag_data) {
C_SaferCond init_ctx;
journaler->init(&init_ctx);
int r = init_ctx.wait();
return -EINVAL;
}
- librbd::journal::ImageClientMeta *image_client_meta =
- boost::get<librbd::journal::ImageClientMeta>(&client_data.client_meta);
+ journal::ImageClientMeta *image_client_meta =
+ boost::get<journal::ImageClientMeta>(&client_data.client_meta);
if (image_client_meta == nullptr) {
return -EINVAL;
}
+ *client_meta = *image_client_meta;
C_SaferCond get_tags_ctx;
Mutex lock("lock");
- *tag_class = image_client_meta->tag_class;
uint64_t tag_tid;
C_DecodeTags *tags_ctx = new C_DecodeTags(
image_ctx->cct, &lock, &tag_tid, tag_data, &get_tags_ctx);
- journaler->get_tags(*tag_class, &tags_ctx->tags, tags_ctx);
+ journaler->get_tags(client_meta->tag_class, &tags_ctx->tags, tags_ctx);
r = get_tags_ctx.wait();
if (r < 0) {
image_ctx->cct->_conf->rbd_journal_commit_age);
bool initialized;
- uint64_t tag_class;
+ journal::ImageClientMeta client_meta;
journal::TagData tag_data;
- int r = open_journaler(image_ctx, &journaler, &initialized, &tag_class,
+ int r = open_journaler(image_ctx, &journaler, &initialized, &client_meta,
&tag_data);
if (r >= 0) {
*mirror_uuid = tag_data.mirror_uuid;
image_ctx->cct->_conf->rbd_journal_commit_age);
bool initialized;
- uint64_t tag_class;
+ journal::ImageClientMeta client_meta;
journal::TagData tag_data;
- int r = open_journaler(image_ctx, &journaler, &initialized, &tag_class,
+ int r = open_journaler(image_ctx, &journaler, &initialized, &client_meta,
&tag_data);
- if (r >= 0) {
- journal::TagData tag_data;
- tag_data.mirror_uuid = mirror_uuid;
+ BOOST_SCOPE_EXIT_ALL(&journaler, &initialized) {
+ if (initialized) {
+ journaler.shut_down();
+ }
+ };
- // TODO: inject current commit position into tag data
- tag_data.predecessor_mirror_uuid = mirror_uuid;
+ if (r < 0) {
+ return r;
+ }
- bufferlist tag_bl;
- ::encode(tag_data, tag_bl);
+ // TODO: inject current commit position into tag data
+ tag_data.mirror_uuid = mirror_uuid;
+ tag_data.predecessor_mirror_uuid = mirror_uuid;
- C_SaferCond allocate_tag_ctx;
- cls::journal::Tag tag;
- journaler.allocate_tag(tag_class, tag_bl, &tag, &allocate_tag_ctx);
+ bufferlist tag_bl;
+ ::encode(tag_data, tag_bl);
- r = allocate_tag_ctx.wait();
- if (r < 0) {
- lderr(cct) << "failed to allocate tag: " << cpp_strerror(r) << dendl;
+ C_SaferCond allocate_tag_ctx;
+ cls::journal::Tag tag;
+ journaler.allocate_tag(client_meta.tag_class, tag_bl, &tag,
+ &allocate_tag_ctx);
+
+ r = allocate_tag_ctx.wait();
+ if (r < 0) {
+ lderr(cct) << "failed to allocate tag: " << cpp_strerror(r) << dendl;
+ return r;
+ }
+
+ return 0;
+}
+
+template <typename I>
+int Journal<I>::request_resync(I *image_ctx) {
+ CephContext *cct = image_ctx->cct;
+ ldout(cct, 20) << __func__ << dendl;
+
+ Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID,
+ image_ctx->cct->_conf->rbd_journal_commit_age);
+
+ bool initialized;
+ journal::ImageClientMeta client_meta;
+ journal::TagData tag_data;
+ int r = open_journaler(image_ctx, &journaler, &initialized, &client_meta,
+ &tag_data);
+ BOOST_SCOPE_EXIT_ALL(&journaler, &initialized) {
+ if (initialized) {
+ journaler.shut_down();
}
+ };
+
+ if (r < 0) {
+ return r;
}
- if (initialized) {
- journaler.shut_down();
+ client_meta.resync_requested = true;
+
+ journal::ClientData client_data(client_meta);
+ bufferlist client_data_bl;
+ ::encode(client_data, client_data_bl);
+
+ C_SaferCond update_client_ctx;
+ journaler.update_client(client_data_bl, &update_client_ctx);
+
+ r = update_client_ctx.wait();
+ if (r < 0) {
+ lderr(cct) << "failed to update client: " << cpp_strerror(r) << dendl;
+ return r;
}
- return r;
+ return 0;
}
template <typename I>
return;
}
- librbd::journal::ImageClientMeta *image_client_meta =
- boost::get<librbd::journal::ImageClientMeta>(&client_data.client_meta);
+ journal::ImageClientMeta *image_client_meta =
+ boost::get<journal::ImageClientMeta>(&client_data.client_meta);
if (image_client_meta == nullptr) {
lderr(cct) << "failed to extract client meta data" << dendl;
destroy_journaler(-EINVAL);