]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: allow to open an image without opening parent image
authorRicardo Dias <rdias@suse.com>
Tue, 10 Jan 2017 15:11:19 +0000 (15:11 +0000)
committerRicardo Dias <rdias@suse.com>
Mon, 16 Jan 2017 18:25:58 +0000 (18:25 +0000)
Fixes: http://tracker.ceph.com/issues/18325
Signed-off-by: Ricardo Dias <rdias@suse.com>
22 files changed:
src/librbd/ImageState.cc
src/librbd/ImageState.h
src/librbd/exclusive_lock/PostAcquireRequest.cc
src/librbd/image/OpenRequest.cc
src/librbd/image/OpenRequest.h
src/librbd/image/RefreshParentRequest.cc
src/librbd/image/RefreshRequest.cc
src/librbd/image/RefreshRequest.h
src/librbd/internal.cc
src/librbd/librbd.cc
src/test/librbd/exclusive_lock/test_mock_PostAcquireRequest.cc
src/test/librbd/image/test_mock_RefreshRequest.cc
src/test/librbd/test_fixture.cc
src/test/librbd/test_internal.cc
src/test/rbd_mirror/image_replayer/test_mock_CreateImageRequest.cc
src/test/rbd_mirror/test_ImageDeleter.cc
src/test/rbd_mirror/test_ImageReplayer.cc
src/test/rbd_mirror/test_PoolWatcher.cc
src/test/rbd_mirror/test_fixture.cc
src/tools/rbd_mirror/ImageDeleter.cc
src/tools/rbd_mirror/image_replayer/OpenImageRequest.cc
src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc

index a94572eaaeec157ee08ba53b09cfce07fe957155..e1ba4a312dc6333a8dc2187ea428142af8bcc21a 100644 (file)
@@ -234,7 +234,8 @@ ImageState<I>::ImageState(I *image_ctx)
   : m_image_ctx(image_ctx), m_state(STATE_UNINITIALIZED),
     m_lock(util::unique_lock_name("librbd::ImageState::m_lock", this)),
     m_last_refresh(0), m_refresh_seq(0),
-    m_update_watchers(new ImageUpdateWatchers(image_ctx->cct)) {
+    m_update_watchers(new ImageUpdateWatchers(image_ctx->cct)),
+    m_skip_open_parent_image(false) {
 }
 
 template <typename I>
@@ -244,19 +245,20 @@ ImageState<I>::~ImageState() {
 }
 
 template <typename I>
-int ImageState<I>::open() {
+int ImageState<I>::open(bool skip_open_parent) {
   C_SaferCond ctx;
-  open(&ctx);
+  open(skip_open_parent, &ctx);
   return ctx.wait();
 }
 
 template <typename I>
-void ImageState<I>::open(Context *on_finish) {
+void ImageState<I>::open(bool skip_open_parent, Context *on_finish) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 20) << __func__ << dendl;
 
   m_lock.Lock();
   assert(m_state == STATE_UNINITIALIZED);
+  m_skip_open_parent_image = skip_open_parent;
 
   Action action(ACTION_TYPE_OPEN);
   action.refresh_seq = m_refresh_seq;
@@ -576,7 +578,7 @@ void ImageState<I>::send_open_unlock() {
     *m_image_ctx, create_context_callback<
       ImageState<I>, &ImageState<I>::handle_open>(this));
   image::OpenRequest<I> *req = image::OpenRequest<I>::create(
-    m_image_ctx, ctx);
+    m_image_ctx, m_skip_open_parent_image, ctx);
 
   m_lock.Unlock();
   req->send();
@@ -641,7 +643,7 @@ void ImageState<I>::send_refresh_unlock() {
     *m_image_ctx, create_context_callback<
       ImageState<I>, &ImageState<I>::handle_refresh>(this));
   image::RefreshRequest<I> *req = image::RefreshRequest<I>::create(
-    *m_image_ctx, false, ctx);
+    *m_image_ctx, false, false, ctx);
 
   m_lock.Unlock();
   req->send();
index 85494c4286eaf7f9047640a3b6b2b8fbf29da976..73433ba8fc8d205ee3519bb13417f8cfa05f16a0 100644 (file)
@@ -25,8 +25,8 @@ public:
   ImageState(ImageCtxT *image_ctx);
   ~ImageState();
 
-  int open();
-  void open(Context *on_finish);
+  int open(bool skip_open_parent);
+  void open(bool skip_open_parent, Context *on_finish);
 
   int close();
   void close(Context *on_finish);
@@ -109,6 +109,8 @@ private:
 
   ImageUpdateWatchers *m_update_watchers;
 
+  bool m_skip_open_parent_image;
+
   bool is_transition_state() const;
   bool is_closed() const;
 
index ed5c466c2eafb94267fd152fc6ad0848bdf50a71..0ac4056bb8164c10480e53d1e9ef04c7e24acc79 100644 (file)
@@ -78,7 +78,7 @@ void PostAcquireRequest<I>::send_refresh() {
   // ImageState is blocked waiting for lock to complete -- safe to directly
   // refresh
   image::RefreshRequest<I> *req = image::RefreshRequest<I>::create(
-    m_image_ctx, true, ctx);
+    m_image_ctx, true, false, ctx);
   req->send();
 }
 
index 026a79525964c4b5673758573892a7801f6d8dc1..87cf6a1459098e41853fa972dd05c89c1b168c1d 100644 (file)
@@ -30,8 +30,10 @@ using util::create_context_callback;
 using util::create_rados_ack_callback;
 
 template <typename I>
-OpenRequest<I>::OpenRequest(I *image_ctx, Context *on_finish)
-  : m_image_ctx(image_ctx), m_on_finish(on_finish), m_error_result(0),
+OpenRequest<I>::OpenRequest(I *image_ctx, bool skip_open_parent,
+                            Context *on_finish)
+  : m_image_ctx(image_ctx), m_skip_open_parent_image(skip_open_parent),
+    m_on_finish(on_finish), m_error_result(0),
     m_last_metadata_key(ImageCtx::METADATA_CONF_PREFIX) {
 }
 
@@ -424,7 +426,7 @@ void OpenRequest<I>::send_refresh() {
 
   using klass = OpenRequest<I>;
   RefreshRequest<I> *req = RefreshRequest<I>::create(
-    *m_image_ctx, false,
+    *m_image_ctx, false, m_skip_open_parent_image,
     create_context_callback<klass, &klass::handle_refresh>(this));
   req->send();
 }
index e71093c901602c8e35ab13395f70ee34ecf2ba73..cd77844516e8fa49cada167f0c5a740398cbb558 100644 (file)
@@ -19,8 +19,9 @@ namespace image {
 template <typename ImageCtxT = ImageCtx>
 class OpenRequest {
 public:
-  static OpenRequest *create(ImageCtxT *image_ctx, Context *on_finish) {
-    return new OpenRequest(image_ctx, on_finish);
+  static OpenRequest *create(ImageCtxT *image_ctx, bool skip_open_parent,
+                             Context *on_finish) {
+    return new OpenRequest(image_ctx, skip_open_parent, on_finish);
   }
 
   void send();
@@ -68,9 +69,10 @@ private:
    * @endverbatim
    */
 
-  OpenRequest(ImageCtxT *image_ctx, Context *on_finish);
+  OpenRequest(ImageCtxT *image_ctx, bool skip_open_parent, Context *on_finish);
 
   ImageCtxT *m_image_ctx;
+  bool m_skip_open_parent_image;
   Context *m_on_finish;
 
   bufferlist m_out_bl;
index a44124f391366202d41ba879d639d718ffad9dbd..28058abe7b557f620eddd7b850979920c02ccfe7 100644 (file)
@@ -120,7 +120,7 @@ void RefreshParentRequest<I>::send_open_parent() {
   Context *ctx = create_async_context_callback(
     m_child_image_ctx, create_context_callback<
       klass, &klass::handle_open_parent, false>(this));
-  OpenRequest<I> *req = OpenRequest<I>::create(m_parent_image_ctx, ctx);
+  OpenRequest<I> *req = OpenRequest<I>::create(m_parent_image_ctx, false, ctx);
   req->send();
 }
 
index 160d6cdd663af79a6dbe08b5752e02de95ed04f6..9884a12bf9ce3219957c4250a4e34db26770b70e 100644 (file)
@@ -28,8 +28,9 @@ using util::create_context_callback;
 
 template <typename I>
 RefreshRequest<I>::RefreshRequest(I &image_ctx, bool acquiring_lock,
-                                  Context *on_finish)
+                                  bool skip_open_parent, Context *on_finish)
   : m_image_ctx(image_ctx), m_acquiring_lock(acquiring_lock),
+    m_skip_open_parent_image(skip_open_parent),
     m_on_finish(create_async_context_callback(m_image_ctx, on_finish)),
     m_error_result(0), m_flush_aio(false), m_exclusive_lock(nullptr),
     m_object_map(nullptr), m_journal(nullptr), m_refresh_parent(nullptr) {
@@ -496,8 +497,8 @@ void RefreshRequest<I>::send_v2_refresh_parent() {
 
     parent_info parent_md;
     int r = get_parent_info(m_image_ctx.snap_id, &parent_md);
-    if (r < 0 ||
-        RefreshParentRequest<I>::is_refresh_required(m_image_ctx, parent_md)) {
+    if (!m_skip_open_parent_image && (r < 0 ||
+        RefreshParentRequest<I>::is_refresh_required(m_image_ctx, parent_md))) {
       CephContext *cct = m_image_ctx.cct;
       ldout(cct, 10) << this << " " << __func__ << dendl;
 
index ff496a1d8b111857359e364e1195fb7c4f82058a..315dd7938b37bf9ff02ccbe4ef9c67714a0353dc 100644 (file)
@@ -27,11 +27,13 @@ template<typename ImageCtxT = ImageCtx>
 class RefreshRequest {
 public:
   static RefreshRequest *create(ImageCtxT &image_ctx, bool acquiring_lock,
-                                Context *on_finish) {
-    return new RefreshRequest(image_ctx, acquiring_lock, on_finish);
+                                bool skip_open_parent, Context *on_finish) {
+    return new RefreshRequest(image_ctx, acquiring_lock, skip_open_parent,
+                              on_finish);
   }
 
-  RefreshRequest(ImageCtxT &image_ctx, bool acquiring_lock, Context *on_finish);
+  RefreshRequest(ImageCtxT &image_ctx, bool acquiring_lock,
+                 bool skip_open_parent, Context *on_finish);
   ~RefreshRequest();
 
   void send();
@@ -104,6 +106,7 @@ private:
 
   ImageCtxT &m_image_ctx;
   bool m_acquiring_lock;
+  bool m_skip_open_parent_image;
   Context *m_on_finish;
 
   int m_error_result;
index 8775cff991927899a60713a05068c060d63828e1..5c2123c2ab1f4d8026e02e5f5a3e5361dc57c6b6 100644 (file)
@@ -710,7 +710,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
 
       for (auto &id_it : info.second) {
        ImageCtx *imctx = new ImageCtx("", id_it, NULL, ioctx, false);
-       int r = imctx->state->open();
+       int r = imctx->state->open(false);
        if (r < 0) {
          lderr(cct) << "error opening image: "
                     << cpp_strerror(r) << dendl;
@@ -1082,7 +1082,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
 
     // make sure parent snapshot exists
     ImageCtx *p_imctx = new ImageCtx(p_name, "", p_snap_name, p_ioctx, true);
-    int r = p_imctx->state->open();
+    int r = p_imctx->state->open(false);
     if (r < 0) {
       lderr(cct) << "error opening parent image: "
                 << cpp_strerror(r) << dendl;
@@ -1224,7 +1224,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
     }
 
     c_imctx = new ImageCtx(c_name, "", NULL, c_ioctx, false);
-    r = c_imctx->state->open();
+    r = c_imctx->state->open(false);
     if (r < 0) {
       lderr(cct) << "Error opening new image: " << cpp_strerror(r) << dendl;
       delete c_imctx;
@@ -1326,7 +1326,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
                   << dstname << dendl;
 
     ImageCtx *ictx = new ImageCtx(srcname, "", "", io_ctx, false);
-    int r = ictx->state->open();
+    int r = ictx->state->open(false);
     if (r < 0) {
       lderr(ictx->cct) << "error opening source image: " << cpp_strerror(r)
                       << dendl;
@@ -1649,7 +1649,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
     bool unknown_format = true;
     ImageCtx *ictx = new ImageCtx(
       (id.empty() ? name : std::string()), id, nullptr, io_ctx, false);
-    int r = ictx->state->open();
+    int r = ictx->state->open(true);
     if (r < 0) {
       ldout(cct, 2) << "error opening image: " << cpp_strerror(-r) << dendl;
       delete ictx;
@@ -2011,7 +2011,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
 
     ImageCtx *dest = new librbd::ImageCtx(destname, "", NULL,
                                          dest_md_ctx, false);
-    r = dest->state->open();
+    r = dest->state->open(false);
     if (r < 0) {
       delete dest;
       lderr(cct) << "failed to read newly created header" << dendl;
@@ -3050,7 +3050,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
         if ((features & RBD_FEATURE_JOURNALING) != 0) {
           ImageCtx *img_ctx = new ImageCtx("", img_pair.second, nullptr,
                                            io_ctx, false);
-          r = img_ctx->state->open();
+          r = img_ctx->state->open(false);
           if (r < 0) {
             lderr(cct) << "error opening image "<< img_pair.first << ": "
                        << cpp_strerror(r) << dendl;
@@ -3098,7 +3098,7 @@ void filter_out_mirror_watchers(ImageCtx *ictx,
           }
         } else {
           ImageCtx *img_ctx = new ImageCtx("", img_id, nullptr, io_ctx, false);
-          r = img_ctx->state->open();
+          r = img_ctx->state->open(false);
           if (r < 0) {
             lderr(cct) << "error opening image id "<< img_id << ": "
                        << cpp_strerror(r) << dendl;
index 5669213a28ec671d664392002ca6e538cc4ee335..97c2ca589dc3f743f62e6c119d79f17dc7c4c13b 100644 (file)
@@ -106,7 +106,7 @@ struct C_OpenAfterCloseComplete : public Context {
   virtual void finish(int r) {
     ldout(ictx->cct, 20) << "C_OpenAfterCloseComplete::finish: r=" << r
                         << dendl;
-    ictx->state->open(new C_OpenComplete(ictx, comp, ictxp, true));
+    ictx->state->open(false, new C_OpenComplete(ictx, comp, ictxp, true));
   }
 };
 
@@ -229,7 +229,7 @@ namespace librbd {
       image.ctx = NULL;
     }
 
-    int r = ictx->state->open();
+    int r = ictx->state->open(false);
     if (r < 0) {
       delete ictx;
       tracepoint(librbd, open_image_exit, r);
@@ -252,7 +252,7 @@ namespace librbd {
       reinterpret_cast<ImageCtx*>(image.ctx)->state->close(
        new C_OpenAfterCloseComplete(ictx, get_aio_completion(c), &image.ctx));
     } else {
-      ictx->state->open(new C_OpenComplete(ictx, get_aio_completion(c),
+      ictx->state->open(false, new C_OpenComplete(ictx, get_aio_completion(c),
                                           &image.ctx));
     }
     tracepoint(librbd, aio_open_image_exit, 0);
@@ -271,7 +271,7 @@ namespace librbd {
       image.ctx = NULL;
     }
 
-    int r = ictx->state->open();
+    int r = ictx->state->open(false);
     if (r < 0) {
       delete ictx;
       tracepoint(librbd, open_image_exit, r);
@@ -294,7 +294,7 @@ namespace librbd {
       reinterpret_cast<ImageCtx*>(image.ctx)->state->close(
        new C_OpenAfterCloseComplete(ictx, get_aio_completion(c), &image.ctx));
     } else {
-      ictx->state->open(new C_OpenComplete(ictx, get_aio_completion(c),
+      ictx->state->open(false, new C_OpenComplete(ictx, get_aio_completion(c),
                                           &image.ctx));
     }
     tracepoint(librbd, aio_open_image_exit, 0);
@@ -2050,7 +2050,7 @@ extern "C" int rbd_open(rados_ioctx_t p, const char *name, rbd_image_t *image,
                                                false);
   tracepoint(librbd, open_image_enter, ictx, ictx->name.c_str(), ictx->id.c_str(), ictx->snap_name.c_str(), ictx->read_only);
 
-  int r = ictx->state->open();
+  int r = ictx->state->open(false);
   if (r < 0) {
     delete ictx;
   } else {
@@ -2071,7 +2071,7 @@ extern "C" int rbd_aio_open(rados_ioctx_t p, const char *name,
                                                false);
   librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
   tracepoint(librbd, aio_open_image_enter, ictx, ictx->name.c_str(), ictx->id.c_str(), ictx->snap_name.c_str(), ictx->read_only, comp->pc);
-  ictx->state->open(new C_OpenComplete(ictx, get_aio_completion(comp), image));
+  ictx->state->open(false, new C_OpenComplete(ictx, get_aio_completion(comp), image));
   tracepoint(librbd, aio_open_image_exit, 0);
   return 0;
 }
@@ -2086,7 +2086,7 @@ extern "C" int rbd_open_read_only(rados_ioctx_t p, const char *name,
                                                true);
   tracepoint(librbd, open_image_enter, ictx, ictx->name.c_str(), ictx->id.c_str(), ictx->snap_name.c_str(), ictx->read_only);
 
-  int r = ictx->state->open();
+  int r = ictx->state->open(false);
   if (r < 0) {
     delete ictx;
   } else {
@@ -2107,7 +2107,8 @@ extern "C" int rbd_aio_open_read_only(rados_ioctx_t p, const char *name,
                                                true);
   librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
   tracepoint(librbd, aio_open_image_enter, ictx, ictx->name.c_str(), ictx->id.c_str(), ictx->snap_name.c_str(), ictx->read_only, comp->pc);
-  ictx->state->open(new C_OpenComplete(ictx, get_aio_completion(comp), image));
+  ictx->state->open(false, new C_OpenComplete(ictx, get_aio_completion(comp),
+                                              image));
   tracepoint(librbd, aio_open_image_exit, 0);
   return 0;
 }
@@ -3332,7 +3333,7 @@ extern "C" int rbd_image_get_group(rados_ioctx_t image_p,
   librados::IoCtx::from_rados_ioctx_t(image_p, io_ctx);
 
   librbd::ImageCtx *ictx = new librbd::ImageCtx(image_name, "", "", io_ctx, false);
-  int r = ictx->state->open();
+  int r = ictx->state->open(false);
   if (r < 0) {
     delete ictx;
     tracepoint(librbd, open_image_exit, r);
index 1b660717ae8225140979ab2412867bd128c5d238..b78521287d228f9329f5eaad47f81dcf1a0336ed 100644 (file)
@@ -41,7 +41,7 @@ struct RefreshRequest<librbd::MockTestImageCtx> {
 
   static RefreshRequest *create(librbd::MockTestImageCtx &image_ctx,
                                 bool acquire_lock_refresh,
-                                Context *on_finish) {
+                                bool skip_open_parent, Context *on_finish) {
     EXPECT_TRUE(acquire_lock_refresh);
     assert(s_instance != nullptr);
     s_instance->on_finish = on_finish;
index c8be0c96847991f84e69298f441a1f6ea9489224..6978fa950ea8da9509732bc94aa2e47f17f52479 100644 (file)
@@ -343,7 +343,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessV1) {
   expect_init_layout(mock_image_ctx);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -368,7 +368,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV1) {
   expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -396,7 +396,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessV2) {
   }
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -429,7 +429,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) {
   expect_add_snap(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -464,7 +464,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
   expect_get_snap_id(mock_image_ctx, "snap", ictx->snap_ids.begin()->second);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -515,7 +515,53 @@ TEST_F(TestMockImageRefreshRequest, SuccessChild) {
   expect_refresh_parent_finalize(mock_image_ctx, *mock_refresh_parent_request, 0);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
+  req->send();
+
+  ASSERT_EQ(0, ctx.wait());
+}
+
+TEST_F(TestMockImageRefreshRequest, SuccessChildDontOpenParent) {
+  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
+
+  librbd::ImageCtx *ictx;
+  librbd::ImageCtx *ictx2 = nullptr;
+  std::string clone_name = get_temp_image_name();
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, snap_create(*ictx, "snap"));
+  ASSERT_EQ(0, snap_protect(*ictx, "snap"));
+  BOOST_SCOPE_EXIT_ALL((&)) {
+    if (ictx2 != nullptr) {
+      close_image(ictx2);
+    }
+
+    librbd::NoOpProgressContext no_op;
+    ASSERT_EQ(0, librbd::remove(m_ioctx, clone_name, "", no_op));
+    ASSERT_EQ(0, ictx->operations->snap_unprotect("snap"));
+  };
+
+  int order = ictx->order;
+  ASSERT_EQ(0, librbd::clone(m_ioctx, m_image_name.c_str(), "snap", m_ioctx,
+                             clone_name.c_str(), ictx->features, &order, 0, 0));
+
+  ASSERT_EQ(0, open_image(clone_name, &ictx2));
+
+  MockRefreshImageCtx mock_image_ctx(*ictx2);
+  MockExclusiveLock mock_exclusive_lock;
+  expect_op_work_queue(mock_image_ctx);
+  expect_test_features(mock_image_ctx);
+
+  InSequence seq;
+  expect_get_mutable_metadata(mock_image_ctx, 0);
+  expect_get_flags(mock_image_ctx, 0);
+  expect_get_group(mock_image_ctx, 0);
+  if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
+    expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
+  }
+
+  C_SaferCond ctx;
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, true, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -576,7 +622,7 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLock) {
   expect_shut_down_exclusive_lock(mock_image_ctx, *mock_exclusive_lock, 0);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -626,7 +672,7 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLockWhileAcquiringLock) {
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, true, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, true, false, &ctx);
   req->send();
 
   ASSERT_EQ(-ERESTART, ctx.wait());
@@ -671,7 +717,7 @@ TEST_F(TestMockImageRefreshRequest, JournalDisabledByPolicy) {
   expect_journal_disabled(mock_journal_policy, true);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -718,7 +764,7 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithExclusiveLock) {
   expect_open_journal(mock_image_ctx, mock_journal, 0);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -759,7 +805,7 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) {
   expect_set_require_lock_on_read(mock_image_ctx);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -805,7 +851,7 @@ TEST_F(TestMockImageRefreshRequest, DisableJournal) {
   expect_unblock_writes(mock_image_ctx);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -843,7 +889,7 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithExclusiveLock) {
   expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -878,7 +924,7 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithoutExclusiveLock) {
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -926,7 +972,7 @@ TEST_F(TestMockImageRefreshRequest, DisableObjectMap) {
   expect_close_object_map(mock_image_ctx, *mock_object_map, 0);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
@@ -964,7 +1010,7 @@ TEST_F(TestMockImageRefreshRequest, OpenObjectMapError) {
   expect_open_object_map(mock_image_ctx, mock_object_map, -EFBIG);
 
   C_SaferCond ctx;
-  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, &ctx);
+  MockRefreshRequest *req = new MockRefreshRequest(mock_image_ctx, false, false, &ctx);
   req->send();
 
   ASSERT_EQ(0, ctx.wait());
index 4b830eb881b86443cfccee3005a2a89ba528f4a3..7b7dc05a7c2a83fb12e95541a2d76fcdf8a49ee6 100644 (file)
@@ -75,7 +75,7 @@ int TestFixture::open_image(const std::string &image_name,
   *ictx = new librbd::ImageCtx(image_name.c_str(), "", NULL, m_ioctx, false);
   m_ictxs.insert(*ictx);
 
-  return (*ictx)->state->open();
+  return (*ictx)->state->open(false);
 }
 
 int TestFixture::snap_create(librbd::ImageCtx &ictx,
index d53e0f683b3a5e426cb6b5e0950fd549748c926d..182886325230efd0c90c1d93e37c3881ca093c34 100644 (file)
@@ -82,7 +82,7 @@ TEST_F(TestInternal, OpenByID) {
    close_image(ictx);
 
    ictx = new librbd::ImageCtx("", id, nullptr, m_ioctx, true);
-   ASSERT_EQ(0, ictx->state->open());
+   ASSERT_EQ(0, ictx->state->open(false));
    ASSERT_EQ(ictx->name, m_image_name);
    close_image(ictx);
 }
index 629f6090fe034b3d1f507b9144cb8ed5e5ff93bc..d18fade118318db97182085a28026ab54ad6d8ad 100644 (file)
@@ -219,7 +219,7 @@ public:
       librbd::ImageCtx *ictx = new librbd::ImageCtx(parent_image_ctx->name,
                                                    "", "", m_remote_io_ctx,
                                                     false);
-      ictx->state->open();
+      ictx->state->open(false);
       EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str(),
                                                 cls::rbd::UserSnapshotNamespace()));
       EXPECT_EQ(0, ictx->operations->snap_protect(snap_name.c_str()));
index 6409868007376bd29cbf32d568b679282fe14b58..88ca29cebc5b6b1679c712a4d20a7a5acdd73d4c 100644 (file)
@@ -70,7 +70,7 @@ public:
     EXPECT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, 1 << 20));
     ImageCtx *ictx = new ImageCtx(m_image_name, "", "", m_local_io_ctx,
                                   false);
-    EXPECT_EQ(0, ictx->state->open());
+    EXPECT_EQ(0, ictx->state->open(false));
     m_local_image_id = ictx->id;
 
     cls::rbd::MirrorImage mirror_image(GLOBAL_IMAGE_ID,
@@ -113,7 +113,7 @@ public:
     if (!ictx) {
       ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                           false);
-      r = ictx->state->open();
+      r = ictx->state->open(false);
       close = (r == 0);
     }
 
@@ -134,7 +134,7 @@ public:
     if (!ictx) {
       ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                           false);
-      EXPECT_EQ(0, ictx->state->open());
+      EXPECT_EQ(0, ictx->state->open(false));
       close = true;
     }
 
@@ -148,7 +148,7 @@ public:
   void create_snapshot(std::string snap_name="snap1", bool protect=false) {
     ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                                   false);
-    EXPECT_EQ(0, ictx->state->open());
+    EXPECT_EQ(0, ictx->state->open(false));
     promote_image(ictx);
 
     EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str(),
@@ -165,7 +165,7 @@ public:
   std::string create_clone() {
     ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                                   false);
-    EXPECT_EQ(0, ictx->state->open());
+    EXPECT_EQ(0, ictx->state->open(false));
     promote_image(ictx);
 
     EXPECT_EQ(0, ictx->operations->snap_create("snap1",
@@ -178,7 +178,7 @@ public:
     std::string clone_id;
     ImageCtx *ictx_clone = new ImageCtx("clone1", "", "", m_local_io_ctx,
                                         false);
-    EXPECT_EQ(0, ictx_clone->state->open());
+    EXPECT_EQ(0, ictx_clone->state->open(false));
     clone_id = ictx_clone->id;
     cls::rbd::MirrorImage mirror_image(GLOBAL_CLONE_IMAGE_ID,
                                 MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
@@ -196,7 +196,7 @@ public:
   void check_image_deleted() {
     ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                                   false);
-    EXPECT_EQ(-ENOENT, ictx->state->open());
+    EXPECT_EQ(-ENOENT, ictx->state->open(false));
     delete ictx;
 
     cls::rbd::MirrorImage mirror_image;
@@ -420,7 +420,7 @@ TEST_F(TestImageDeleter, Delete_NonExistent_Image_Without_MirroringState) {
 TEST_F(TestImageDeleter, Fail_Delete_NonPrimary_Image) {
   ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                                 false);
-  EXPECT_EQ(0, ictx->state->open());
+  EXPECT_EQ(0, ictx->state->open(false));
 
   m_deleter->schedule_image_delete(_rados, m_local_pool_id, m_local_image_id,
       m_image_name, GLOBAL_IMAGE_ID);
@@ -439,7 +439,7 @@ TEST_F(TestImageDeleter, Fail_Delete_NonPrimary_Image) {
 TEST_F(TestImageDeleter, Retry_Failed_Deletes) {
   ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                                 false);
-  EXPECT_EQ(0, ictx->state->open());
+  EXPECT_EQ(0, ictx->state->open(false));
 
   m_deleter->set_failed_timer_interval(2);
 
@@ -467,7 +467,7 @@ TEST_F(TestImageDeleter, Retry_Failed_Deletes) {
 TEST_F(TestImageDeleter, Delete_Is_Idempotent) {
   ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
                                 false);
-  EXPECT_EQ(0, ictx->state->open());
+  EXPECT_EQ(0, ictx->state->open(false));
 
   m_deleter->schedule_image_delete(_rados, m_local_pool_id, m_local_image_id,
       m_image_name, GLOBAL_IMAGE_ID);
index 363ff6d23c8a77e396af0a48c995bc16fe2854ae..e4231f75cc06fc9fdc0d9ad3f85c3899e2bdd96e 100644 (file)
@@ -195,7 +195,7 @@ public:
   {
     librbd::ImageCtx *ictx = new librbd::ImageCtx(image_name.c_str(),
                                                  "", "", ioctx, readonly);
-    EXPECT_EQ(0, ictx->state->open());
+    EXPECT_EQ(0, ictx->state->open(false));
     *ictxp = ictx;
   }
 
index 257d6b6c70e06ad22de24995033c28bec3034c81..e177abaf441c5bce24dd6e9276304611df59bbd9 100644 (file)
@@ -128,7 +128,7 @@ TestPoolWatcher() : m_lock("TestPoolWatcherLock"),
     {
       librbd::ImageCtx *ictx = new librbd::ImageCtx(parent_image_name.c_str(),
                                                    "", "", pioctx, false);
-      ictx->state->open();
+      ictx->state->open(false);
       EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str(),
                                                 cls::rbd::UserSnapshotNamespace()));
       EXPECT_EQ(0, ictx->operations->snap_protect(snap_name.c_str()));
index 6e0a8954a0903c0db96201d17552e502e37a0546..0d6fc4d5a9ba7dace18eb16d43f93ce0aa78db28 100644 (file)
@@ -90,7 +90,7 @@ int TestFixture::open_image(librados::IoCtx &io_ctx,
   *image_ctx = new librbd::ImageCtx(image_name.c_str(), "", NULL, io_ctx,
                                     false);
   m_image_ctxs.insert(*image_ctx);
-  return (*image_ctx)->state->open();
+  return (*image_ctx)->state->open(false);
 }
 
 int TestFixture::create_snap(librbd::ImageCtx *image_ctx, const char* snap_name,
index 773ad493b004966344340667d2c6e465b435a394..39bf57dd813fa3f6f27c6ffec3dab769ed229979 100644 (file)
@@ -332,7 +332,7 @@ bool ImageDeleter::process_image_delete() {
 
     ImageCtx *imgctx = new ImageCtx("", m_active_delete->local_image_id,
                                     nullptr, ioctx, false);
-    r = imgctx->state->open();
+    r = imgctx->state->open(false);
     if (r < 0) {
       derr << "error opening image id " << m_active_delete->local_image_id
            << ": " << cpp_strerror(r) << dendl;
index c908d0977666b5b40f7cc148dd4e021412c87079..3ffdaad6ea6bf805f7e3602eb650e6e144835475 100644 (file)
@@ -45,7 +45,7 @@ void OpenImageRequest<I>::send_open_image() {
   Context *ctx = create_context_callback<
     OpenImageRequest<I>, &OpenImageRequest<I>::handle_open_image>(
       this);
-  (*m_image_ctx)->state->open(ctx);
+  (*m_image_ctx)->state->open(false, ctx);
 }
 
 template <typename I>
index 99cb253a81c807fcefd28840c53ad1bfdf6bd144..7862b906a8e083ca08b79780b4aba2f58f1e150c 100644 (file)
@@ -102,7 +102,7 @@ void OpenLocalImageRequest<I>::send_open_image() {
   Context *ctx = create_context_callback<
     OpenLocalImageRequest<I>, &OpenLocalImageRequest<I>::handle_open_image>(
       this);
-  (*m_local_image_ctx)->state->open(ctx);
+  (*m_local_image_ctx)->state->open(false, ctx);
 }
 
 template <typename I>