]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: new async journal open state machine
authorJason Dillaman <dillaman@redhat.com>
Tue, 18 Oct 2016 03:51:51 +0000 (23:51 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 31 Oct 2016 14:57:14 +0000 (10:57 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/CMakeLists.txt
src/librbd/Journal.cc
src/librbd/Journal.h
src/librbd/journal/OpenRequest.cc [new file with mode: 0644]
src/librbd/journal/OpenRequest.h [new file with mode: 0644]
src/test/librbd/CMakeLists.txt
src/test/librbd/journal/test_mock_OpenRequest.cc [new file with mode: 0644]
src/test/librbd/test_mock_Journal.cc

index 7f2d863c18fa774e3a4395d1cb0188c42cca3211..e6b9c5d4d15a66287b5cd5658458740ad653552e 100644 (file)
@@ -45,6 +45,7 @@ set(librbd_internal_srcs
   image_watcher/RewatchRequest.cc
   journal/RemoveRequest.cc
   journal/CreateRequest.cc
+  journal/OpenRequest.cc
   journal/Replay.cc
   journal/StandardPolicy.cc
   journal/Utils.cc
index 999c26b9a9510b45f1be8f8e69aa083cbb8da1d6..c16ac34a352d98a727b5695512e2e0201bc1f703 100644 (file)
@@ -6,6 +6,7 @@
 #include "librbd/AioObjectRequest.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/journal/OpenRequest.h"
 #include "librbd/journal/Replay.h"
 #include "cls/journal/cls_journal_types.h"
 #include "journal/Journaler.h"
@@ -210,54 +211,8 @@ void get_tags(CephContext *cct, J *journaler,
   req->send();
 }
 
-template <typename J>
-int open_journaler(CephContext *cct, J *journaler,
-                   cls::journal::Client *client,
-                   journal::ImageClientMeta *client_meta,
-                   uint64_t *tag_tid, journal::TagData *tag_data) {
-  C_SaferCond init_ctx;
-  journaler->init(&init_ctx);
-  int r = init_ctx.wait();
-  if (r < 0) {
-    return r;
-  }
-
-  r = journaler->get_cached_client(Journal<ImageCtx>::IMAGE_CLIENT_ID, client);
-  if (r < 0) {
-    return r;
-  }
-
-  librbd::journal::ClientData client_data;
-  bufferlist::iterator bl_it = client->data.begin();
-  try {
-    ::decode(client_data, bl_it);
-  } catch (const buffer::error &err) {
-    return -EINVAL;
-  }
-
-  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");
-  C_DecodeTags *tags_ctx = new C_DecodeTags(
-      cct, &lock, tag_tid, tag_data, &get_tags_ctx);
-  journaler->get_tags(client_meta->tag_class, &tags_ctx->tags, tags_ctx);
-
-  r = get_tags_ctx.wait();
-  if (r < 0) {
-    return r;
-  }
-  return 0;
-}
-
 template <typename J>
 int allocate_journaler_tag(CephContext *cct, J *journaler,
-                           const cls::journal::Client &client,
                            uint64_t tag_class,
                            const journal::TagPredecessor &predecessor,
                            const std::string &mirror_uuid,
@@ -542,16 +497,22 @@ int Journal<I>::request_resync(I *image_ctx) {
 
   Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID, {});
 
-  cls::journal::Client client;
+  Mutex lock("lock");
   journal::ImageClientMeta client_meta;
   uint64_t tag_tid;
   journal::TagData tag_data;
-  int r = open_journaler(image_ctx->cct, &journaler, &client, &client_meta,
-                         &tag_tid, &tag_data);
+
+  C_SaferCond open_ctx;
+  auto open_req = journal::OpenRequest<I>::create(image_ctx, &journaler, &lock,
+                                                  &client_meta, &tag_tid,
+                                                  &tag_data, &open_ctx);
+  open_req->send();
+
   BOOST_SCOPE_EXIT_ALL(&journaler) {
     journaler.shut_down();
   };
 
+  int r = open_ctx.wait();
   if (r < 0) {
     return r;
   }
@@ -581,16 +542,22 @@ int Journal<I>::promote(I *image_ctx) {
 
   Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID, {});
 
-  cls::journal::Client client;
+  Mutex lock("lock");
   journal::ImageClientMeta client_meta;
   uint64_t tag_tid;
   journal::TagData tag_data;
-  int r = open_journaler(image_ctx->cct, &journaler, &client, &client_meta,
-                         &tag_tid, &tag_data);
+
+  C_SaferCond open_ctx;
+  auto open_req = journal::OpenRequest<I>::create(image_ctx, &journaler, &lock,
+                                                  &client_meta, &tag_tid,
+                                                  &tag_data, &open_ctx);
+  open_req->send();
+
   BOOST_SCOPE_EXIT_ALL(&journaler) {
     journaler.shut_down();
   };
 
+  int r = open_ctx.wait();
   if (r < 0) {
     return r;
   }
@@ -608,7 +575,7 @@ int Journal<I>::promote(I *image_ctx) {
   }
 
   cls::journal::Tag new_tag;
-  r = allocate_journaler_tag(cct, &journaler, client, client_meta.tag_class,
+  r = allocate_journaler_tag(cct, &journaler, client_meta.tag_class,
                              predecessor, LOCAL_MIRROR_UUID, &new_tag);
   if (r < 0) {
     return r;
@@ -765,8 +732,8 @@ int Journal<I>::demote() {
     }
 
     cls::journal::Tag new_tag;
-    r = allocate_journaler_tag(cct, m_journaler, client, m_tag_class,
-                               predecessor, ORPHAN_MIRROR_UUID, &new_tag);
+    r = allocate_journaler_tag(cct, m_journaler, m_tag_class, predecessor,
+                               ORPHAN_MIRROR_UUID, &new_tag);
     if (r < 0) {
       return r;
     }
@@ -1241,9 +1208,15 @@ void Journal<I>::create_journaler() {
   m_journaler = new Journaler(m_work_queue, m_timer, m_timer_lock,
                              m_image_ctx.md_ctx, m_image_ctx.id,
                              IMAGE_CLIENT_ID, settings);
-  m_journaler->init(create_async_context_callback(
+  m_journaler->add_listener(&m_metadata_listener);
+
+  Context *ctx = create_async_context_callback(
     m_image_ctx, create_context_callback<
-      Journal<I>, &Journal<I>::handle_initialized>(this)));
+      Journal<I>, &Journal<I>::handle_open>(this));
+  auto open_req = journal::OpenRequest<I>::create(&m_image_ctx, m_journaler,
+                                                  &m_lock, &m_client_meta,
+                                                  &m_tag_tid, &m_tag_data, ctx);
+  open_req->send();
 }
 
 template <typename I>
@@ -1331,7 +1304,7 @@ void Journal<I>::start_append() {
 }
 
 template <typename I>
-void Journal<I>::handle_initialized(int r) {
+void Journal<I>::handle_open(int r) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << this << " " << __func__ << ": r=" << r << dendl;
 
@@ -1346,67 +1319,11 @@ void Journal<I>::handle_initialized(int r) {
     return;
   }
 
+  m_tag_class = m_client_meta.tag_class;
   m_max_append_size = m_journaler->get_max_append_size();
-  ldout(cct, 20) << this << " max_append_size=" << m_max_append_size << dendl;
-
-  // locate the master image client record
-  cls::journal::Client client;
-  r = m_journaler->get_cached_client(Journal<ImageCtx>::IMAGE_CLIENT_ID,
-                                     &client);
-  if (r < 0) {
-    lderr(cct) << this << " " << __func__ << ": "
-               << "failed to locate master image client" << dendl;
-    destroy_journaler(r);
-    return;
-  }
-
-  librbd::journal::ClientData client_data;
-  bufferlist::iterator bl = client.data.begin();
-  try {
-    ::decode(client_data, bl);
-  } catch (const buffer::error &err) {
-    lderr(cct) << this << " " << __func__ << ": "
-               << "failed to decode client meta data: " << err.what()
-               << dendl;
-    destroy_journaler(-EINVAL);
-    return;
-  }
-
-  journal::ImageClientMeta *image_client_meta =
-    boost::get<journal::ImageClientMeta>(&client_data.client_meta);
-  if (image_client_meta == nullptr) {
-    lderr(cct) << this << " " << __func__ << ": "
-               << "failed to extract client meta data" << dendl;
-    destroy_journaler(-EINVAL);
-    return;
-  }
-
-  m_tag_class = image_client_meta->tag_class;
   ldout(cct, 20) << this << " " << __func__ << ": "
-                 << "client: " << client << ", "
-                 << "image meta: " << *image_client_meta << dendl;
-
-  C_DecodeTags *tags_ctx = new C_DecodeTags(
-    cct, &m_lock, &m_tag_tid, &m_tag_data, create_async_context_callback(
-      m_image_ctx, create_context_callback<
-        Journal<I>, &Journal<I>::handle_get_tags>(this)));
-  m_journaler->get_tags(m_tag_class, &tags_ctx->tags, tags_ctx);
-
-  m_journaler->add_listener(&m_metadata_listener);
-}
-
-template <typename I>
-void Journal<I>::handle_get_tags(int r) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": r=" << r << dendl;
-
-  Mutex::Locker locker(m_lock);
-  assert(m_state == STATE_INITIALIZING);
-
-  if (r < 0) {
-    destroy_journaler(r);
-    return;
-  }
+                 << "tag_class=" << m_tag_class << ", "
+                 << "max_append_size=" << m_max_append_size << dendl;
 
   transition_state(STATE_REPLAYING, 0);
   m_journal_replay = journal::Replay<I>::create(m_image_ctx);
index f1824a257cc2a18f5bce2cff522acba79041e296..4b70b99eb8ab56df4fa33b11103c31c38a4f5f6d 100644 (file)
@@ -284,6 +284,7 @@ private:
   uint64_t m_max_append_size = 0;
   uint64_t m_tag_class = 0;
   uint64_t m_tag_tid = 0;
+  journal::ImageClientMeta m_client_meta;
   journal::TagData m_tag_data;
 
   int m_error_result;
@@ -343,8 +344,7 @@ private:
 
   void start_append();
 
-  void handle_initialized(int r);
-  void handle_get_tags(int r);
+  void handle_open(int r);
 
   void handle_replay_ready();
   void handle_replay_complete(int r);
diff --git a/src/librbd/journal/OpenRequest.cc b/src/librbd/journal/OpenRequest.cc
new file mode 100644 (file)
index 0000000..6dbaf6e
--- /dev/null
@@ -0,0 +1,144 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/journal/OpenRequest.h"
+#include "common/dout.h"
+#include "common/errno.h"
+#include "common/WorkQueue.h"
+#include "journal/Journaler.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/Journal.h"
+#include "librbd/Utils.h"
+#include "librbd/journal/Types.h"
+#include "librbd/journal/Utils.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::journal::OpenRequest: " << this << " " \
+                           << __func__ << ": "
+
+namespace librbd {
+namespace journal {
+
+using librbd::util::create_async_context_callback;
+using librbd::util::create_context_callback;
+using util::C_DecodeTags;
+
+template <typename I>
+OpenRequest<I>::OpenRequest(I *image_ctx, Journaler *journaler, Mutex *lock,
+                            journal::ImageClientMeta *client_meta,
+                            uint64_t *tag_tid, journal::TagData *tag_data,
+                            Context *on_finish)
+  : m_image_ctx(image_ctx), m_journaler(journaler), m_lock(lock),
+    m_client_meta(client_meta), m_tag_tid(tag_tid), m_tag_data(tag_data),
+    m_on_finish(on_finish) {
+}
+
+template <typename I>
+void OpenRequest<I>::send() {
+  send_init();
+}
+
+template <typename I>
+void OpenRequest<I>::send_init() {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  m_journaler->init(create_async_context_callback(
+    *m_image_ctx, create_context_callback<
+      OpenRequest<I>, &OpenRequest<I>::handle_init>(this)));
+}
+
+template <typename I>
+void OpenRequest<I>::handle_init(int r) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << "failed to initialize journal: " << cpp_strerror(r)
+               << dendl;
+    finish(r);
+    return;
+  }
+
+  // locate the master image client record
+  cls::journal::Client client;
+  r = m_journaler->get_cached_client(Journal<ImageCtx>::IMAGE_CLIENT_ID,
+                                     &client);
+  if (r < 0) {
+    lderr(cct) << "failed to locate master image client" << dendl;
+    finish(r);
+    return;
+  }
+
+  librbd::journal::ClientData client_data;
+  bufferlist::iterator bl = client.data.begin();
+  try {
+    ::decode(client_data, bl);
+  } catch (const buffer::error &err) {
+    lderr(cct) << "failed to decode client meta data: " << err.what()
+               << dendl;
+    finish(-EINVAL);
+    return;
+  }
+
+  journal::ImageClientMeta *image_client_meta =
+    boost::get<journal::ImageClientMeta>(&client_data.client_meta);
+  if (image_client_meta == nullptr) {
+    lderr(cct) << this << " " << __func__ << ": "
+               << "failed to extract client meta data" << dendl;
+    finish(-EINVAL);
+    return;
+  }
+
+  ldout(cct, 20) << this << " " << __func__ << ": "
+                 << "client: " << client << ", "
+                 << "image meta: " << *image_client_meta << dendl;
+
+  m_tag_class = image_client_meta->tag_class;
+  {
+    Mutex::Locker locker(*m_lock);
+    *m_client_meta = *image_client_meta;
+  }
+
+  send_get_tags();
+}
+
+template <typename I>
+void OpenRequest<I>::send_get_tags() {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 20) << dendl;
+
+  C_DecodeTags *tags_ctx = new C_DecodeTags(
+    cct, m_lock, m_tag_tid, m_tag_data, create_async_context_callback(
+      *m_image_ctx, create_context_callback<
+        OpenRequest<I>, &OpenRequest<I>::handle_get_tags>(this)));
+  m_journaler->get_tags(m_tag_class, &tags_ctx->tags, tags_ctx);
+}
+
+template <typename I>
+void OpenRequest<I>::handle_get_tags(int r) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 20) << "r=" << r << dendl;
+
+  if (r < 0) {
+    lderr(cct) << this << " " << __func__ << ": "
+               << "failed to decode journal tags: " << cpp_strerror(r) << dendl;
+  }
+
+  finish(r);
+}
+
+template <typename I>
+void OpenRequest<I>::finish(int r) {
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 20) << "r=" << r << dendl;
+
+  m_on_finish->complete(r);
+  delete this;
+}
+
+} // namespace journal
+} // namespace librbd
+
+template class librbd::journal::OpenRequest<librbd::ImageCtx>;
diff --git a/src/librbd/journal/OpenRequest.h b/src/librbd/journal/OpenRequest.h
new file mode 100644 (file)
index 0000000..f71d8c5
--- /dev/null
@@ -0,0 +1,85 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_JOURNAL_OPEN_REQUEST_H
+#define CEPH_LIBRBD_JOURNAL_OPEN_REQUEST_H
+
+#include "include/int_types.h"
+#include "librbd/journal/TypeTraits.h"
+
+struct Context;
+struct Mutex;
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace journal {
+
+struct ImageClientMeta;
+struct TagData;
+
+template <typename ImageCtxT = ImageCtx>
+class OpenRequest {
+public:
+  typedef typename TypeTraits<ImageCtxT>::Journaler Journaler;
+
+  static OpenRequest* create(ImageCtxT *image_ctx, Journaler *journaler,
+                             Mutex *lock, journal::ImageClientMeta *client_meta,
+                             uint64_t *tag_tid, journal::TagData *tag_data,
+                             Context *on_finish) {
+    return new OpenRequest(image_ctx, journaler, lock, client_meta, tag_tid,
+                           tag_data, on_finish);
+  }
+
+  OpenRequest(ImageCtxT *image_ctx, Journaler *journaler, Mutex *lock,
+              journal::ImageClientMeta *client_meta, uint64_t *tag_tid,
+              journal::TagData *tag_data, Context *on_finish);
+
+  void send();
+
+private:
+  /**
+   * @verbatim
+   *
+   * <start>
+   *    |
+   *    v
+   *  INIT
+   *    |
+   *    v
+   * GET_TAGS
+   *    |
+   *    v
+   * <finish>
+   *
+   * @endverbatim
+   */
+
+
+  ImageCtxT *m_image_ctx;
+  Journaler *m_journaler;
+  Mutex *m_lock;
+  journal::ImageClientMeta *m_client_meta;
+  uint64_t *m_tag_tid;
+  journal::TagData *m_tag_data;
+  Context *m_on_finish;
+
+  uint64_t m_tag_class = 0;
+
+  void send_init();
+  void handle_init(int r);
+
+  void send_get_tags();
+  void handle_get_tags(int r);
+
+  void finish(int r);
+
+};
+
+} // namespace journal
+} // namespace librbd
+
+extern template class librbd::journal::OpenRequest<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_JOURNAL_OPEN_REQUEST_H
index 9e07fa0a9f9767d46d6b0510d6e96a37d047efda..c29cab3ff544bc8224e25174c94a1369f6db833d 100644 (file)
@@ -35,6 +35,7 @@ set(unittest_librbd_srcs
   exclusive_lock/test_mock_ReleaseRequest.cc
   image/test_mock_RefreshRequest.cc
   image_watcher/test_mock_RewatchRequest.cc
+  journal/test_mock_OpenRequest.cc
   journal/test_mock_Replay.cc
   object_map/test_mock_InvalidateRequest.cc
   object_map/test_mock_LockRequest.cc
diff --git a/src/test/librbd/journal/test_mock_OpenRequest.cc b/src/test/librbd/journal/test_mock_OpenRequest.cc
new file mode 100644 (file)
index 0000000..98bc429
--- /dev/null
@@ -0,0 +1,194 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/librbd/test_mock_fixture.h"
+#include "test/librbd/test_support.h"
+#include "test/librbd/mock/MockImageCtx.h"
+#include "test/journal/mock/MockJournaler.h"
+#include "common/Mutex.h"
+#include "cls/journal/cls_journal_types.h"
+#include "librbd/journal/OpenRequest.h"
+#include "librbd/journal/Types.h"
+
+namespace librbd {
+
+namespace {
+
+struct MockTestImageCtx : public MockImageCtx {
+  MockTestImageCtx(librbd::ImageCtx& image_ctx) : MockImageCtx(image_ctx) {
+  }
+};
+
+} // anonymous namespace
+
+namespace journal {
+
+template <>
+struct TypeTraits<MockTestImageCtx> {
+  typedef ::journal::MockJournaler Journaler;
+};
+
+} // namespace journal
+} // namespace librbd
+
+// template definitions
+#include "librbd/journal/OpenRequest.cc"
+template class librbd::journal::OpenRequest<librbd::MockTestImageCtx>;
+
+namespace librbd {
+namespace journal {
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::WithArg;
+
+class TestMockJournalOpenRequest : public TestMockFixture {
+public:
+  typedef OpenRequest<MockTestImageCtx> MockOpenRequest;
+
+  TestMockJournalOpenRequest() : m_lock("m_lock") {
+  }
+
+  void expect_init_journaler(::journal::MockJournaler &mock_journaler, int r) {
+    EXPECT_CALL(mock_journaler, init(_))
+                  .WillOnce(CompleteContext(r, NULL));
+  }
+
+  void expect_get_journaler_cached_client(::journal::MockJournaler &mock_journaler,
+                                          int r) {
+    journal::ImageClientMeta image_client_meta;
+    image_client_meta.tag_class = 345;
+
+    journal::ClientData client_data;
+    client_data.client_meta = image_client_meta;
+
+    cls::journal::Client client;
+    ::encode(client_data, client.data);
+
+    EXPECT_CALL(mock_journaler, get_cached_client("", _))
+                  .WillOnce(DoAll(SetArgPointee<1>(client),
+                                  Return(r)));
+  }
+
+  void expect_get_journaler_tags(MockImageCtx &mock_image_ctx,
+                                 ::journal::MockJournaler &mock_journaler,
+                                 int r) {
+    journal::TagData tag_data;
+    tag_data.mirror_uuid = "remote mirror";
+
+    bufferlist tag_data_bl;
+    ::encode(tag_data, tag_data_bl);
+
+    ::journal::Journaler::Tags tags = {{0, 345, {}}, {1, 345, tag_data_bl}};
+    EXPECT_CALL(mock_journaler, get_tags(345, _, _))
+                  .WillOnce(DoAll(SetArgPointee<1>(tags),
+                                  WithArg<2>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue))));
+  }
+
+  Mutex m_lock;
+  ImageClientMeta m_client_meta;
+  uint64_t m_tag_tid = 0;
+  TagData m_tag_data;
+};
+
+TEST_F(TestMockJournalOpenRequest, Success) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockTestImageCtx mock_image_ctx(*ictx);
+  ::journal::MockJournaler mock_journaler;
+
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, 0);
+
+  C_SaferCond ctx;
+  auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler,
+                                     &m_lock, &m_client_meta, &m_tag_tid,
+                                     &m_tag_data, &ctx);
+  req->send();
+  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(345U, m_client_meta.tag_class);
+  ASSERT_EQ(1U, m_tag_tid);
+  ASSERT_EQ("remote mirror", m_tag_data.mirror_uuid);
+}
+
+TEST_F(TestMockJournalOpenRequest, InitError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockTestImageCtx mock_image_ctx(*ictx);
+  ::journal::MockJournaler mock_journaler;
+
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_init_journaler(mock_journaler, -ENOENT);
+
+  C_SaferCond ctx;
+  auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler,
+                                     &m_lock, &m_client_meta, &m_tag_tid,
+                                     &m_tag_data, &ctx);
+  req->send();
+  ASSERT_EQ(-ENOENT, ctx.wait());
+}
+
+TEST_F(TestMockJournalOpenRequest, GetCachedClientError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockTestImageCtx mock_image_ctx(*ictx);
+  ::journal::MockJournaler mock_journaler;
+
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, -EINVAL);
+
+  C_SaferCond ctx;
+  auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler,
+                                     &m_lock, &m_client_meta, &m_tag_tid,
+                                     &m_tag_data, &ctx);
+  req->send();
+  ASSERT_EQ(-EINVAL, ctx.wait());
+}
+
+TEST_F(TestMockJournalOpenRequest, GetTagsError) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockTestImageCtx mock_image_ctx(*ictx);
+  ::journal::MockJournaler mock_journaler;
+
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_init_journaler(mock_journaler, 0);
+  expect_get_journaler_cached_client(mock_journaler, 0);
+  expect_get_journaler_tags(mock_image_ctx, mock_journaler, -EBADMSG);
+
+  C_SaferCond ctx;
+  auto req = MockOpenRequest::create(&mock_image_ctx, &mock_journaler,
+                                     &m_lock, &m_client_meta, &m_tag_tid,
+                                     &m_tag_data, &ctx);
+  req->send();
+  ASSERT_EQ(-EBADMSG, ctx.wait());
+}
+
+} // namespace journal
+} // namespace librbd
index 6622cf349fafd735fc5c9d660c059dfe27c79e33..f4e6065bafd649b579098e4ca066c505fe297c14 100644 (file)
@@ -17,6 +17,7 @@
 #include "librbd/journal/Replay.h"
 #include "librbd/journal/RemoveRequest.h"
 #include "librbd/journal/CreateRequest.h"
+#include "librbd/journal/OpenRequest.h"
 #include "librbd/journal/Types.h"
 #include "librbd/journal/TypeTraits.h"
 #include "gmock/gmock.h"
@@ -154,6 +155,32 @@ public:
 
 MockCreate *MockCreate::s_instance = nullptr;
 
+template<>
+class OpenRequest<MockJournalImageCtx> {
+public:
+  TagData *tag_data;
+  Context *on_finish;
+  static OpenRequest *s_instance;
+  static OpenRequest *create(MockJournalImageCtx *image_ctx,
+                             ::journal::MockJournalerProxy *journaler,
+                             Mutex *lock, journal::ImageClientMeta *client_meta,
+                             uint64_t *tag_tid, journal::TagData *tag_data,
+                             Context *on_finish) {
+    assert(s_instance != nullptr);
+    s_instance->tag_data = tag_data;
+    s_instance->on_finish = on_finish;
+    return s_instance;
+  }
+
+  OpenRequest() {
+    s_instance = this;
+  }
+
+  MOCK_METHOD0(send, void());
+};
+
+OpenRequest<MockJournalImageCtx> *OpenRequest<MockJournalImageCtx>::s_instance = nullptr;
+
 } // namespace journal
 } // namespace librbd
 
@@ -183,6 +210,7 @@ class TestMockJournal : public TestMockFixture {
 public:
   typedef journal::MockReplay MockJournalReplay;
   typedef Journal<MockJournalImageCtx> MockJournal;
+  typedef journal::OpenRequest<MockJournalImageCtx> MockJournalOpenRequest;
 
   typedef std::function<void(::journal::ReplayHandler*)> ReplayAction;
   typedef std::list<Context *> Contexts;
@@ -217,9 +245,20 @@ public:
     EXPECT_CALL(mock_journaler, construct());
   }
 
-  void expect_init_journaler(::journal::MockJournaler &mock_journaler, int r) {
-    EXPECT_CALL(mock_journaler, init(_))
-                  .WillOnce(CompleteContext(r, NULL));
+  void expect_open_journaler(MockImageCtx &mock_image_ctx,
+                             ::journal::MockJournaler &mock_journaler,
+                             MockJournalOpenRequest &mock_open_request,
+                             bool primary, int r) {
+    EXPECT_CALL(mock_journaler, add_listener(_))
+                  .WillOnce(SaveArg<0>(&m_listener));
+    EXPECT_CALL(mock_open_request, send())
+                  .WillOnce(DoAll(Invoke([&mock_open_request, primary]() {
+                                    if (!primary) {
+                                      mock_open_request.tag_data->mirror_uuid = "remote mirror uuid";
+                                    }
+                                  }),
+                                  FinishRequest(&mock_open_request, r,
+                                                &mock_image_ctx)));
   }
 
   void expect_shut_down_journaler(::journal::MockJournaler &mock_journaler) {
@@ -234,12 +273,6 @@ public:
                   .WillOnce(Return(max_size));
   }
 
-  void expect_get_journaler_cached_client(::journal::MockJournaler &mock_journaler, int r) {
-    journal::ImageClientMeta image_client_meta;
-    image_client_meta.tag_class = 0;
-    expect_get_journaler_cached_client(mock_journaler, image_client_meta, r);
-  }
-
   void expect_get_journaler_cached_client(::journal::MockJournaler &mock_journaler,
                                           const journal::ImageClientMeta &client_meta,
                                           int r) {
@@ -254,25 +287,6 @@ public:
                                   Return(r)));
   }
 
-  void expect_get_journaler_tags(MockImageCtx &mock_image_ctx,
-                                 ::journal::MockJournaler &mock_journaler,
-                                 bool primary, int r) {
-    journal::TagData tag_data;
-    if (!primary) {
-      tag_data.mirror_uuid = "remote mirror uuid";
-    }
-
-    bufferlist tag_data_bl;
-    ::encode(tag_data, tag_data_bl);
-
-    ::journal::Journaler::Tags tags = {{0, 0, {}}, {1, 0, tag_data_bl}};
-    EXPECT_CALL(mock_journaler, get_tags(0, _, _))
-                  .WillOnce(DoAll(SetArgPointee<1>(tags),
-                                  WithArg<2>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue))));
-    EXPECT_CALL(mock_journaler, add_listener(_))
-                  .WillOnce(SaveArg<0>(&m_listener));
-  }
-
   void expect_get_journaler_tags(MockImageCtx &mock_image_ctx,
                                  ::journal::MockJournaler &mock_journaler,
                                  uint64_t start_after_tag_tid,
@@ -440,15 +454,15 @@ public:
   void open_journal(MockJournalImageCtx &mock_image_ctx,
                     MockJournal &mock_journal,
                     ::journal::MockJournaler &mock_journaler,
+                    MockJournalOpenRequest &mock_open_request,
                     bool primary = true) {
     expect_op_work_queue(mock_image_ctx);
 
     InSequence seq;
     expect_construct_journaler(mock_journaler);
-    expect_init_journaler(mock_journaler, 0);
+    expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                          primary, 0);
     expect_get_max_append_size(mock_journaler, 1 << 16);
-    expect_get_journaler_cached_client(mock_journaler, 0);
-    expect_get_journaler_tags(mock_image_ctx, mock_journaler, primary, 0);
     expect_start_replay(
       mock_image_ctx, mock_journaler,
       std::bind(&invoke_replay_complete, _1, 0));
@@ -492,11 +506,11 @@ TEST_F(TestMockJournal, StateTransitions) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_ready, _1));
@@ -540,55 +554,14 @@ TEST_F(TestMockJournal, InitError) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, -EINVAL);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, -EINVAL);
   expect_shut_down_journaler(mock_journaler);
   ASSERT_EQ(-EINVAL, when_open(mock_journal));
 }
 
-TEST_F(TestMockJournal, GetCachedClientError) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
-  MockJournalImageCtx mock_image_ctx(*ictx);
-  MockJournal mock_journal(mock_image_ctx);
-  expect_op_work_queue(mock_image_ctx);
-
-  InSequence seq;
-
-  ::journal::MockJournaler mock_journaler;
-  expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
-  expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, -ENOENT);
-  expect_shut_down_journaler(mock_journaler);
-  ASSERT_EQ(-ENOENT, when_open(mock_journal));
-}
-
-TEST_F(TestMockJournal, GetTagsError) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
-  MockJournalImageCtx mock_image_ctx(*ictx);
-  MockJournal mock_journal(mock_image_ctx);
-  expect_op_work_queue(mock_image_ctx);
-
-  InSequence seq;
-
-  ::journal::MockJournaler mock_journaler;
-  expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
-  expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, -EBADMSG);
-  expect_shut_down_journaler(mock_journaler);
-  ASSERT_EQ(-EBADMSG, when_open(mock_journal));
-}
-
 TEST_F(TestMockJournal, ReplayCompleteError) {
   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
 
@@ -602,11 +575,11 @@ TEST_F(TestMockJournal, ReplayCompleteError) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_complete, _1, -EINVAL));
@@ -618,10 +591,9 @@ TEST_F(TestMockJournal, ReplayCompleteError) {
 
   // replay failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_complete, _1, 0));
@@ -649,11 +621,11 @@ TEST_F(TestMockJournal, FlushReplayError) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_ready, _1));
@@ -670,10 +642,9 @@ TEST_F(TestMockJournal, FlushReplayError) {
 
   // replay flush failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_complete, _1, 0));
@@ -701,11 +672,11 @@ TEST_F(TestMockJournal, CorruptEntry) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_ready, _1));
@@ -720,10 +691,9 @@ TEST_F(TestMockJournal, CorruptEntry) {
 
   // replay failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_complete, _1, 0));
@@ -750,11 +720,11 @@ TEST_F(TestMockJournal, StopError) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_complete, _1, 0));
@@ -782,11 +752,11 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
 
   InSequence seq;
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
 
   expect_start_replay(
     mock_image_ctx, mock_journaler,
@@ -811,10 +781,9 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
 
   // replay write-to-disk failure should result in replay-restart
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler, {
       std::bind(&invoke_replay_complete, _1, 0)
@@ -864,11 +833,11 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
   InSequence seq;
 
   ::journal::MockJournaler mock_journaler;
+  MockJournalOpenRequest mock_open_request;
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_ready, _1));
@@ -889,10 +858,9 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
   // replay write-to-disk failure should result in replay-restart
   expect_shut_down_journaler(mock_journaler);
   expect_construct_journaler(mock_journaler);
-  expect_init_journaler(mock_journaler, 0);
+  expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
+                        true, 0);
   expect_get_max_append_size(mock_journaler, 1 << 16);
-  expect_get_journaler_cached_client(mock_journaler, 0);
-  expect_get_journaler_tags(mock_image_ctx, mock_journaler, true, 0);
   expect_start_replay(
     mock_image_ctx, mock_journaler,
     std::bind(&invoke_replay_complete, _1, 0));
@@ -940,7 +908,8 @@ TEST_F(TestMockJournal, EventAndIOCommitOrder) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -986,7 +955,8 @@ TEST_F(TestMockJournal, AppendWriteEvent) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1025,7 +995,8 @@ TEST_F(TestMockJournal, EventCommitError) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1065,7 +1036,8 @@ TEST_F(TestMockJournal, EventCommitErrorWithPendingWriteback) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1106,7 +1078,8 @@ TEST_F(TestMockJournal, IOCommitError) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1135,7 +1108,8 @@ TEST_F(TestMockJournal, FlushCommitPosition) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1157,7 +1131,8 @@ TEST_F(TestMockJournal, ExternalReplay) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1185,7 +1160,8 @@ TEST_F(TestMockJournal, ExternalReplayFailure) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1213,7 +1189,8 @@ TEST_F(TestMockJournal, AppendDisabled) {
   MockJournalPolicy mock_journal_policy;
 
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
   BOOST_SCOPE_EXIT_ALL(&) {
     close_journal(mock_journal, mock_journaler);
   };
@@ -1241,7 +1218,8 @@ TEST_F(TestMockJournal, CloseListenerEvent) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request);
 
   struct Listener : public journal::Listener {
     C_SaferCond ctx;
@@ -1273,7 +1251,9 @@ TEST_F(TestMockJournal, ResyncRequested) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler, false);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request,
+               false);
 
   struct Listener : public journal::Listener {
     C_SaferCond ctx;
@@ -1323,7 +1303,9 @@ TEST_F(TestMockJournal, ForcePromoted) {
   MockJournalImageCtx mock_image_ctx(*ictx);
   MockJournal mock_journal(mock_image_ctx);
   ::journal::MockJournaler mock_journaler;
-  open_journal(mock_image_ctx, mock_journal, mock_journaler, false);
+  MockJournalOpenRequest mock_open_request;
+  open_journal(mock_image_ctx, mock_journal, mock_journaler, mock_open_request,
+               false);
 
   struct Listener : public journal::Listener {
     C_SaferCond ctx;