]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
qa: add new test case for pulling error
authorxie xingguo <xie.xingguo@zte.com.cn>
Tue, 2 Apr 2019 08:17:52 +0000 (16:17 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Thu, 4 Apr 2019 03:04:43 +0000 (11:04 +0800)
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
qa/standalone/osd/osd-rep-recov-eio.sh
src/common/legacy_config_opts.h
src/common/options.cc
src/osd/ReplicatedBackend.cc

index af4dfa3370bbb08bbca1031e02e435e6a3906ad5..adf6fc7967a0fa8eb0f15a8679de02684f071c19 100755 (executable)
@@ -122,15 +122,27 @@ function rados_get_data() {
     COUNT=$(ceph pg dump --format=json-pretty | jq ".pg_map.osd_stats_sum.num_shards_repaired")
     test "$COUNT" = "1" || return 1
 
+    local object_osds=($(get_osds $poolname $objname))
+    local primary=${object_osds[0]}
+    local bad_peer=${object_osds[1]}
     inject_$inject rep data $poolname $objname $dir 0 || return 1
     inject_$inject rep data $poolname $objname $dir 1 || return 1
+    # Force primary to pull from the bad peer, so we can repair it too!
+    set_config osd $primary osd_debug_feed_pullee $bad_peer || return 1
+    rados_get $dir $poolname $objname || return 1
+
+    # Wait until automatic repair of bad peer is done
+    wait_for_clean || return 1
+
+    inject_$inject rep data $poolname $objname $dir 0 || return 1
+    inject_$inject rep data $poolname $objname $dir 2 || return 1
     rados_get $dir $poolname $objname || return 1
 
     COUNT=$(ceph pg $pgid query | jq '.info.stats.stat_sum.num_objects_repaired')
-    test "$COUNT" = "2" || return 1
+    test "$COUNT" = "3" || return 1
     flush_pg_stats
     COUNT=$(ceph pg dump --format=json-pretty | jq ".pg_map.osd_stats_sum.num_shards_repaired")
-    test "$COUNT" = "2" || return 1
+    test "$COUNT" = "4" || return 1
 
     inject_$inject rep data $poolname $objname $dir 0 || return 1
     inject_$inject rep data $poolname $objname $dir 1 || return 1
@@ -139,10 +151,10 @@ function rados_get_data() {
 
     # After hang another repair couldn't happen, so count stays the same
     COUNT=$(ceph pg $pgid query | jq '.info.stats.stat_sum.num_objects_repaired')
-    test "$COUNT" = "2" || return 1
+    test "$COUNT" = "3" || return 1
     flush_pg_stats
     COUNT=$(ceph pg dump --format=json-pretty | jq ".pg_map.osd_stats_sum.num_shards_repaired")
-    test "$COUNT" = "2" || return 1
+    test "$COUNT" = "4" || return 1
 }
 
 function TEST_rados_get_with_eio() {
index c10a906e65957fb23002b850378136ba2a580afb..822cc0d81e4fd9b0589a23bcfbbaa2d81431f8de 100644 (file)
@@ -643,6 +643,7 @@ OPTION(osd_read_ec_check_for_errors, OPT_BOOL) // return error if any ec shard h
 // Only use clone_overlap for recovery if there are fewer than
 // osd_recover_clone_overlap_limit entries in the overlap set
 OPTION(osd_recover_clone_overlap_limit, OPT_INT)
+OPTION(osd_debug_feed_pullee, OPT_INT)
 
 OPTION(osd_backfill_scan_min, OPT_INT)
 OPTION(osd_backfill_scan_max, OPT_INT)
index 8a35540db451fd4620b143a9de553a2f6b9fed06..8ce5e35c8ffcaebdb705c936d53ef23695c14a95 100644 (file)
@@ -3123,6 +3123,11 @@ std::vector<Option> get_global_options() {
     .set_default(10)
     .set_description(""),
 
+    Option("osd_debug_feed_pullee", Option::TYPE_INT, Option::LEVEL_DEV)
+    .set_default(-1)
+    .set_description("Feed a pullee, and force primary to pull "
+                     "a currently missing object from it"),
+
     Option("osd_backfill_scan_min", Option::TYPE_INT, Option::LEVEL_ADVANCED)
     .set_default(64)
     .set_description(""),
index 23bc3b9bf55db26379a5b0a8a3d67a74eae6115f..269adf64b1191875ddf79f0094a325954ec4d143 100644 (file)
@@ -1299,10 +1299,22 @@ void ReplicatedBackend::prepare_pull(
   ceph_assert(!q->second.empty());
 
   // pick a pullee
-  auto p = q->second.begin();
-  std::advance(p,
-               util::generate_random_number<int>(0,
-                                                 q->second.size() - 1));
+  auto p = q->second.end();
+  if (cct->_conf->osd_debug_feed_pullee >= 0) {
+    for (auto it = q->second.begin(); it != q->second.end(); it++) {
+      if (it->osd == cct->_conf->osd_debug_feed_pullee) {
+        p = it;
+        break;
+      }
+    }
+  }
+  if (p == q->second.end()) {
+    // probably because user feed a wrong pullee
+    p = q->second.begin();
+    std::advance(p,
+                 util::generate_random_number<int>(0,
+                                                   q->second.size() - 1));
+  }
   ceph_assert(get_osdmap()->is_up(p->osd));
   pg_shard_t fromshard = *p;