]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: option to automatically resync after journal client disconnect
authorMykola Golub <mgolub@mirantis.com>
Wed, 10 Aug 2016 10:46:46 +0000 (13:46 +0300)
committerJason Dillaman <dillaman@redhat.com>
Tue, 11 Oct 2016 16:41:19 +0000 (12:41 -0400)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
(cherry picked from commit 77fd6a1c2016262d734b0bb5387e6b6a41232e8b)

Conflicts:
src/common/config_opts.h: trivial resolution

qa/workunits/rbd/rbd_mirror.sh
src/common/config_opts.h
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/test/librbd/mock/MockImageCtx.h
src/test/rbd_mirror/test_ImageReplayer.cc
src/tools/rbd_mirror/ImageReplayer.cc

index d553e7b9fc3d316774c423c6253838c614ef6cc5..e6860397b74c17b8fce9e0e852eea395decfe36d 100755 (executable)
@@ -279,4 +279,20 @@ wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
 test -n "$(get_mirror_position ${CLUSTER2} ${POOL} ${image})"
 compare_images ${POOL} ${image}
 
+testlog " - rbd_mirroring_resync_after_disconnect config option"
+set_image_meta ${CLUSTER1} ${POOL} ${image} \
+              conf_rbd_mirroring_resync_after_disconnect true
+disconnect_image ${CLUSTER2} ${POOL} ${image}
+wait_for_image_present ${CLUSTER1} ${POOL} ${image} 'deleted'
+wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
+wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
+test -n "$(get_mirror_position ${CLUSTER2} ${POOL} ${image})"
+compare_images ${POOL} ${image}
+set_image_meta ${CLUSTER1} ${POOL} ${image} \
+              conf_rbd_mirroring_resync_after_disconnect false
+disconnect_image ${CLUSTER2} ${POOL} ${image}
+test -z "$(get_mirror_position ${CLUSTER2} ${POOL} ${image})"
+wait_for_image_replay_stopped ${CLUSTER1} ${POOL} ${image}
+test_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+error' 'disconnected'
+
 echo OK
index ba1c48c40648e5755eeb79fbce84372bb19e4cd3..3795f0ec3e6c2f998b09ee005622ca2292638351 100644 (file)
@@ -1172,6 +1172,7 @@ OPTION(rbd_enable_alloc_hint, OPT_BOOL, true) // when writing a object, it will
 OPTION(rbd_tracing, OPT_BOOL, false) // true if LTTng-UST tracepoints should be enabled
 OPTION(rbd_validate_pool, OPT_BOOL, true) // true if empty pools should be validated for RBD compatibility
 OPTION(rbd_validate_names, OPT_BOOL, true) // true if image specs should be validated
+OPTION(rbd_mirroring_resync_after_disconnect, OPT_BOOL, false) // automatically start image resync after mirroring is disconnected due to being laggy
 
 /*
  * The following options change the behavior for librbd's image creation methods that
index c1d21f070cb405984899be910690bcb2d277e7ae..4226d4274713820796cec6f5bab0bb9de147e7cb 100644 (file)
@@ -930,7 +930,8 @@ struct C_InvalidateCache : public Context {
         "rbd_journal_object_flush_age", false)(
         "rbd_journal_pool", false)(
         "rbd_journal_max_payload_bytes", false)(
-        "rbd_journal_max_concurrent_object_sets", false);
+        "rbd_journal_max_concurrent_object_sets", false)(
+        "rbd_mirroring_resync_after_disconnect", false);
 
     md_config_t local_config_t;
     std::map<std::string, bufferlist> res;
@@ -987,6 +988,7 @@ struct C_InvalidateCache : public Context {
     ASSIGN_OPTION(journal_pool);
     ASSIGN_OPTION(journal_max_payload_bytes);
     ASSIGN_OPTION(journal_max_concurrent_object_sets);
+    ASSIGN_OPTION(mirroring_resync_after_disconnect);
   }
 
   ExclusiveLock<ImageCtx> *ImageCtx::create_exclusive_lock() {
index 552d8a8eb5d27d7401f444f084ce32ba63dc2dca..b8a3bf6cf24a8d717b5e0aff118c07042095c990 100644 (file)
@@ -184,6 +184,7 @@ namespace librbd {
     std::string journal_pool;
     uint32_t journal_max_payload_bytes;
     int journal_max_concurrent_object_sets;
+    bool mirroring_resync_after_disconnect;
 
     LibrbdAdminSocketHook *asok_hook;
 
index 3dd3962d169ffbd01196cbb9c22c62d912a3b4c1..f7283a72bc6deeed180d17ac6d399cccd569aa6b 100644 (file)
@@ -93,7 +93,9 @@ struct MockImageCtx {
       journal_pool(image_ctx.journal_pool),
       journal_max_payload_bytes(image_ctx.journal_max_payload_bytes),
       journal_max_concurrent_object_sets(
-          image_ctx.journal_max_concurrent_object_sets)
+          image_ctx.journal_max_concurrent_object_sets),
+      mirroring_resync_after_disconnect(
+          image_ctx.mirroring_resync_after_disconnect)
   {
     md_ctx.dup(image_ctx.md_ctx);
     data_ctx.dup(image_ctx.data_ctx);
@@ -260,6 +262,7 @@ struct MockImageCtx {
   std::string journal_pool;
   uint32_t journal_max_payload_bytes;
   int journal_max_concurrent_object_sets;
+  bool mirroring_resync_after_disconnect;
 };
 
 } // namespace librbd
index bb95dff819d9456a1819056ea2543a743c06bc71..d484188a60067b76b1a18807777260be5ffa708d 100644 (file)
@@ -829,6 +829,9 @@ TEST_F(TestImageReplayer, Disconnect)
 {
   bootstrap();
 
+  // Make sure rbd_mirroring_resync_after_disconnect is not set
+  EXPECT_EQ(0, m_local_cluster->conf_set("rbd_mirroring_resync_after_disconnect", "false"));
+
   // Test start fails if disconnected
 
   librbd::ImageCtx *ictx;
@@ -889,4 +892,24 @@ TEST_F(TestImageReplayer, Disconnect)
   C_SaferCond cond4;
   m_replayer->start(&cond4);
   ASSERT_EQ(-ENOTCONN, cond4.wait());
+
+  // Test automatic resync if rbd_mirroring_resync_after_disconnect is set
+
+  EXPECT_EQ(0, m_local_cluster->conf_set("rbd_mirroring_resync_after_disconnect", "true"));
+
+  // Resync is flagged on first start attempt
+  C_SaferCond cond5;
+  m_replayer->start(&cond5);
+  ASSERT_EQ(-ENOTCONN, cond5.wait());
+  C_SaferCond delete_cond1;
+  m_image_deleter->wait_for_scheduled_deletion(
+    m_local_ioctx.get_id(), m_replayer->get_global_image_id(), &delete_cond1);
+  EXPECT_EQ(0, delete_cond1.wait());
+
+  C_SaferCond cond6;
+  m_replayer->start(&cond6);
+  ASSERT_EQ(0, cond6.wait());
+  wait_for_replay_complete();
+
+  stop();
 }
index 58df5d081b11173ddc86eb7b326c210756b6a1af..263eebc91b6b2a85f5032c665cb5eaf562109831 100644 (file)
@@ -531,6 +531,10 @@ void ImageReplayer<I>::handle_init_remote_journaler(int r) {
 
   if (client.state != cls::journal::CLIENT_STATE_CONNECTED) {
     dout(5) << "client flagged disconnected, stopping image replay" << dendl;
+    if (m_local_image_ctx->mirroring_resync_after_disconnect) {
+      Mutex::Locker locker(m_lock);
+      m_stopping_for_resync = true;
+    }
     on_start_fail(-ENOTCONN, "disconnected");
     return;
   }