]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
RADOS: fix write op hangs 11143/head
authorYunchuan Wen <yunchuan.wen@kylin-cloud.com>
Tue, 20 Sep 2016 03:54:56 +0000 (11:54 +0800)
committerYunchuan Wen <yunchuan.wen@kylin-cloud.com>
Tue, 20 Sep 2016 04:46:28 +0000 (12:46 +0800)
if primary OSD handle a write op and do_osd_ops return errro code,
record_write_error will try to record it into pglog and send log message
to replica.
but if replica OSD crash right now, the primary OSD will call
on_change to free all repop, and do_update_log_missing_reply will not
be called, so the write op will lost and hangs.

this patch fix it.

Signed-off-by: Yunchuan Wen <yunchuan.wen@kylin-cloud.com>
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h

index cd8d91f598c5719b0cb59f78d5b77c2ac0602c1e..7a342fff7546992e8ed1f08c12fa4a8c8e5e05a7 100644 (file)
@@ -2309,7 +2309,9 @@ void ReplicatedPG::record_write_error(OpRequestRef op, const hobject_t &soid,
        dout(10) << " sending commit on " << *m << " " << reply << dendl;
        osd->send_message_osd_client(reply, m->get_connection());
       }
-      ));
+      ),
+    op
+  );
 }
 
 ReplicatedPG::cache_result_t ReplicatedPG::maybe_handle_cache_detail(
@@ -8753,10 +8755,12 @@ ReplicatedPG::RepGather *ReplicatedPG::new_repop(
 
 boost::intrusive_ptr<ReplicatedPG::RepGather> ReplicatedPG::new_repop(
   ObcLockManager &&manager,
+  OpRequestRef &&op,
   boost::optional<std::function<void(void)> > &&on_complete)
 {
   RepGather *repop = new RepGather(
     std::move(manager),
+    std::move(op),
     std::move(on_complete),
     osd->get_tid(),
     info.last_complete);
@@ -8812,7 +8816,8 @@ void ReplicatedPG::simple_opc_submit(OpContextUPtr ctx)
 void ReplicatedPG::submit_log_entries(
   const list<pg_log_entry_t> &entries,
   ObcLockManager &&manager,
-  boost::optional<std::function<void(void)> > &&on_complete)
+  boost::optional<std::function<void(void)> > &&on_complete,
+  OpRequestRef op)
 {
   dout(10) << __func__ << entries << dendl;
   assert(is_primary());
@@ -8827,6 +8832,7 @@ void ReplicatedPG::submit_log_entries(
   if (get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_JEWEL)) {
     repop = new_repop(
       std::move(manager),
+      std::move(op),
       std::move(on_complete));
   }
   for (set<pg_shard_t>::const_iterator i = actingbackfill.begin();
@@ -10325,6 +10331,7 @@ void ReplicatedPG::on_change(ObjectStore::Transaction *t)
   // this will requeue ops we were working on but didn't finish, and
   // any dups
   apply_and_flush_repops(is_primary());
+  cancel_log_updates();
 
   // do this *after* apply_and_flush_repops so that we catch any newly
   // registered watches.
index 66bc96827aa18a5d930b28a0a4d78cbaac0695ee..fa2895a1c2adc7a2e7e804144fbed1610a1fb995 100644 (file)
@@ -699,9 +699,11 @@ public:
 
     RepGather(
       ObcLockManager &&manager,
+      OpRequestRef &&o,
       boost::optional<std::function<void(void)> > &&on_complete,
       ceph_tid_t rt,
       eversion_t lc) :
+      op(o),
       queue_item(this),
       nref(1),
       rep_tid(rt),
@@ -845,6 +847,7 @@ protected:
     ceph_tid_t rep_tid);
   boost::intrusive_ptr<RepGather> new_repop(
     ObcLockManager &&manager,
+    OpRequestRef &&op,
     boost::optional<std::function<void(void)> > &&on_complete);
   void remove_repop(RepGather *repop);
 
@@ -860,7 +863,8 @@ protected:
   void submit_log_entries(
     const list<pg_log_entry_t> &entries,
     ObcLockManager &&manager,
-    boost::optional<std::function<void(void)> > &&on_complete);
+    boost::optional<std::function<void(void)> > &&on_complete,
+    OpRequestRef op = OpRequestRef());
   struct LogUpdateCtx {
     boost::intrusive_ptr<RepGather> repop;
     set<pg_shard_t> waiting_on;