diff mbox

[06/39] mds: make table client/server tolerate duplicated message

Message ID 1363531902-24909-7-git-send-email-zheng.z.yan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yan, Zheng March 17, 2013, 2:51 p.m. UTC
From: "Yan, Zheng" <zheng.z.yan@intel.com>

Anchor client re-sends queries when the anchor server becomes active.
So it's possible to get duplicated query reply.

When the table server recovers, the clients re-send commits to the
server, the server re-sends 'agree' messages to the clients. When
the clients receive the 'agree' messages, they may send another
commit/rollback message to the server.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
---
 src/mds/AnchorClient.cc   |  4 +++-
 src/mds/AnchorServer.cc   |  6 ++++--
 src/mds/MDSTableServer.cc | 22 ++++++++++++++++------
 3 files changed, 23 insertions(+), 9 deletions(-)

Comments

Gregory Farnum March 29, 2013, 10 p.m. UTC | #1
I believe this patch has been outdated thanks to the tid exchange
you're doing now, right?
-Greg

On Sun, Mar 17, 2013 at 7:51 AM, Yan, Zheng <zheng.z.yan@intel.com> wrote:
> From: "Yan, Zheng" <zheng.z.yan@intel.com>
>
> Anchor client re-sends queries when the anchor server becomes active.
> So it's possible to get duplicated query reply.
>
> When the table server recovers, the clients re-send commits to the
> server, the server re-sends 'agree' messages to the clients. When
> the clients receive the 'agree' messages, they may send another
> commit/rollback message to the server.
>
> Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
> ---
>  src/mds/AnchorClient.cc   |  4 +++-
>  src/mds/AnchorServer.cc   |  6 ++++--
>  src/mds/MDSTableServer.cc | 22 ++++++++++++++++------
>  3 files changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/src/mds/AnchorClient.cc b/src/mds/AnchorClient.cc
> index d7da9d1..bcc8710 100644
> --- a/src/mds/AnchorClient.cc
> +++ b/src/mds/AnchorClient.cc
> @@ -41,7 +41,9 @@ void AnchorClient::handle_query_result(class MMDSTableRequest *m)
>    ::decode(ino, p);
>    ::decode(trace, p);
>
> -  assert(pending_lookup.count(ino));
> +  if (!pending_lookup.count(ino))
> +    return;
> +
>    list<_pending_lookup> ls;
>    ls.swap(pending_lookup[ino]);
>    pending_lookup.erase(ino);
> diff --git a/src/mds/AnchorServer.cc b/src/mds/AnchorServer.cc
> index 6f37e53..594bf7b 100644
> --- a/src/mds/AnchorServer.cc
> +++ b/src/mds/AnchorServer.cc
> @@ -213,10 +213,12 @@ bool AnchorServer::check_pending(version_t tid, MMDSTableRequest *req, list<Cont
>        ++p;
>      }
>      assert(p != pending.end());
> -    assert(p->second == NULL);
>      // not the earliest pending operation, wait if it's a commit
>      if (req) {
> -      p->second = new C_MDS_RetryMessage(mds, req);
> +      if (p->second == NULL)
> +       p->second = new C_MDS_RetryMessage(mds, req);
> +      else
> +       req->put(); // duplicated commit
>        return false;
>      }
>    }
> diff --git a/src/mds/MDSTableServer.cc b/src/mds/MDSTableServer.cc
> index 07c7d26..730606f 100644
> --- a/src/mds/MDSTableServer.cc
> +++ b/src/mds/MDSTableServer.cc
> @@ -120,15 +120,25 @@ void MDSTableServer::_commit_logged(MMDSTableRequest *req)
>  void MDSTableServer::handle_rollback(MMDSTableRequest *req)
>  {
>    dout(7) << "handle_rollback " << *req << dendl;
> -  _rollback(req->get_tid());
> -  _note_rollback(req->get_tid());
> -  mds->mdlog->start_submit_entry(new ETableServer(table, TABLESERVER_OP_ROLLBACK, 0, -1,
> -                                                 req->get_tid(), version));
> +
> +  version_t tid = req->get_tid();
> +  if (pending_for_mds.count(tid)) {
> +    _rollback(tid);
> +    _note_rollback(tid);
> +    mds->mdlog->start_submit_entry(new ETableServer(table, TABLESERVER_OP_ROLLBACK, 0, -1,
> +         tid, version));
> +  } else if (tid <= version) {
> +    dout(0) << "got rollback for tid " << tid << " <= " << version
> +           << ", already rollbacked or committed." << dendl;
> +  }
> +  else {
> +    // wtf.
> +    dout(0) << "got rollbacked for tid " << tid << " > " << version << dendl;
> +    assert(tid <= version);
> +  }
>    req->put();
>  }
>
> -
> -
>  // SERVER UPDATE
>
>  void MDSTableServer::do_server_update(bufferlist& bl)
> --
> 1.7.11.7
>
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/src/mds/AnchorClient.cc b/src/mds/AnchorClient.cc
index d7da9d1..bcc8710 100644
--- a/src/mds/AnchorClient.cc
+++ b/src/mds/AnchorClient.cc
@@ -41,7 +41,9 @@  void AnchorClient::handle_query_result(class MMDSTableRequest *m)
   ::decode(ino, p);
   ::decode(trace, p);
 
-  assert(pending_lookup.count(ino));
+  if (!pending_lookup.count(ino))
+    return;
+
   list<_pending_lookup> ls;
   ls.swap(pending_lookup[ino]);
   pending_lookup.erase(ino);
diff --git a/src/mds/AnchorServer.cc b/src/mds/AnchorServer.cc
index 6f37e53..594bf7b 100644
--- a/src/mds/AnchorServer.cc
+++ b/src/mds/AnchorServer.cc
@@ -213,10 +213,12 @@  bool AnchorServer::check_pending(version_t tid, MMDSTableRequest *req, list<Cont
       ++p;
     }
     assert(p != pending.end());
-    assert(p->second == NULL);
     // not the earliest pending operation, wait if it's a commit
     if (req) {
-      p->second = new C_MDS_RetryMessage(mds, req);
+      if (p->second == NULL)
+	p->second = new C_MDS_RetryMessage(mds, req);
+      else
+	req->put(); // duplicated commit
       return false;
     }
   }
diff --git a/src/mds/MDSTableServer.cc b/src/mds/MDSTableServer.cc
index 07c7d26..730606f 100644
--- a/src/mds/MDSTableServer.cc
+++ b/src/mds/MDSTableServer.cc
@@ -120,15 +120,25 @@  void MDSTableServer::_commit_logged(MMDSTableRequest *req)
 void MDSTableServer::handle_rollback(MMDSTableRequest *req)
 {
   dout(7) << "handle_rollback " << *req << dendl;
-  _rollback(req->get_tid());
-  _note_rollback(req->get_tid());
-  mds->mdlog->start_submit_entry(new ETableServer(table, TABLESERVER_OP_ROLLBACK, 0, -1, 
-						  req->get_tid(), version));
+
+  version_t tid = req->get_tid();
+  if (pending_for_mds.count(tid)) {
+    _rollback(tid);
+    _note_rollback(tid);
+    mds->mdlog->start_submit_entry(new ETableServer(table, TABLESERVER_OP_ROLLBACK, 0, -1,
+	  tid, version));
+  } else if (tid <= version) {
+    dout(0) << "got rollback for tid " << tid << " <= " << version
+	    << ", already rollbacked or committed." << dendl;
+  }
+  else {
+    // wtf.
+    dout(0) << "got rollbacked for tid " << tid << " > " << version << dendl;
+    assert(tid <= version);
+  }
   req->put();
 }
 
-
-
 // SERVER UPDATE
 
 void MDSTableServer::do_server_update(bufferlist& bl)