]> git.apps.os.sepia.ceph.com Git - ceph-ci.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)
committerMykola Golub <mgolub@mirantis.com>
Mon, 5 Sep 2016 09:48:47 +0000 (12:48 +0300)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
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 71f8d7efae13756928ae915936f25235b285ba1a..5b016f0b6f5b4836662b50372cf97fad5195c0aa 100755 (executable)
@@ -303,4 +303,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 f797f6034b5ad341ab4d27358c84529f96277ce7..664cf6de3b493d0eb8f473c91171679436f124f1 100644 (file)
@@ -1212,6 +1212,7 @@ OPTION(rbd_tracing, OPT_BOOL, false) // true if LTTng-UST tracepoints should be
 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_auto_exclusive_lock_until_manual_request, OPT_BOOL, true) // whether to automatically acquire/release exclusive lock until it is explicitly requested, i.e. before we know the user of librbd is properly using the lock API
+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 e8054353e942c5b58544c4b0f44daa8f7a5838cb..d5437fd1edd74a5a2950e3cd9397f1b0dc3d9c3a 100644 (file)
@@ -945,7 +945,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;
@@ -1002,6 +1003,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 f087fc027d45ae1e1bdd7e90387b6e6e828131ab..1855641267ef229d11b5c93f1d9669fc28214f86 100644 (file)
@@ -189,6 +189,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 ddb4af3df4731e9d8453a395af392e9d64a2ad0a..ffccf95f9ee824465d277183d20944f13fc19d7f 100644 (file)
@@ -94,7 +94,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);
@@ -263,6 +265,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 49592c3774b76b5814d899990133fc6456918ebb..38b0b41aee78e4e23a2731f5f9fcf2a4094d9598 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 6d3a6154d6d2a3dc797e836f9c1c3346b1a0a8f7..8e65e4bd92d7359fa9a50ac4bb73c41b62d21385 100644 (file)
@@ -532,6 +532,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;
   }