]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/Paxos: fix sync restart
authorSage Weil <sage@inktank.com>
Fri, 5 Jul 2013 02:33:06 +0000 (19:33 -0700)
committerSage Weil <sage@inktank.com>
Fri, 5 Jul 2013 17:07:15 +0000 (10:07 -0700)
If we have a sync going, and an election intervenes, the client will
try to continue by sending a new start_chunks request.  In order to
ensure that we get all of the paxos commits from our original starting
point (and thus properly update the keys from which they started),
only pay attention if they *also* send their current last_committed
version.  Otherwise, start them at the beginning.

Signed-off-by: Sage Weil <sage@inktank.com>
src/mon/Monitor.cc
src/mon/Monitor.h

index bb328325f109d9aa577260d26636dab0b38778eb..22c6d58100c6dbea1442f7766f0d05d658d1d2f2 100644 (file)
@@ -1227,14 +1227,30 @@ void Monitor::handle_sync_start_chunks(MMonSync *m)
   }
 
   SyncEntity sync = get_sync_entity(other, this);
-  sync->version = paxos->get_version();
 
   if (!m->last_key.first.empty() && !m->last_key.second.empty()) {
-    sync->last_received_key = m->last_key;
-    dout(10) << __func__ << " set last received key to ("
-            << sync->last_received_key.first << ","
-            << sync->last_received_key.second << ")" << dendl;
+    if (m->version == 0) {
+      // uh-oh; we can't do this safely without a proper version marker
+      // because we don't know what paxos commits they got from the
+      // previous keys (if any!), and we may miss some.
+      dout(1) << __func__ << " got mid-sync start_chunks from " << other
+             << " without version marker; ignoring last_received_key marker" << dendl;
+      sync->version = paxos->get_version();
+    } else {
+      sync->version = m->version;
+      sync->last_received_key = m->last_key;
+      dout(10) << __func__ << " set last received key to ("
+              << sync->last_received_key.first << ","
+              << sync->last_received_key.second << ")" << dendl;
+    }
+  } else {
+    sync->version = paxos->get_version();
   }
+  dout(10) << __func__ << " version " << sync->version
+          << " last received key ("
+          << sync->last_received_key.first << ","
+          << sync->last_received_key.second << ")"
+          << dendl;
 
   sync->sync_init();
 
@@ -1550,8 +1566,10 @@ void Monitor::sync_start_chunks(SyncEntity provider)
                        g_conf->mon_sync_timeout);
   MMonSync *msg = new MMonSync(MMonSync::OP_START_CHUNKS);
   pair<string,string> last_key = provider->last_received_key;
-  if (!last_key.first.empty() && !last_key.second.empty())
+  if (!last_key.first.empty() && !last_key.second.empty()) {
     msg->last_key = last_key;
+    msg->version = store->get("paxos", "last_committed");
+  }
 
   assert(g_conf->mon_sync_requester_kill_at != 4);
   messenger->send_message(msg, provider->entity);
index e6bdc8f2af4946ce7a5a94d21177d9dcd88a714a..6cc4382d5ee2f424f8893d7ec44de598d3bc85eb 100644 (file)
@@ -604,9 +604,6 @@ private:
 
       string prefix("paxos");
       paxos_synchronizer = mon->store->get_synchronizer(prefix);
-      version = mon->paxos->get_version();
-      generic_dout(10) << __func__ << " version " << version << dendl;
-
       synchronizer = mon->store->get_synchronizer(last_received_key,
                                                  sync_targets);
       sync_update();