summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-05-13 20:39:36 +0200
committerSage Weil <sage@inktank.com>2013-05-13 20:39:36 +0200
commit110411630986e083d9012d12a5b6c68b0dcd872c (patch)
tree7e84a8d7d96f13ff784b0bd1f117386f6c7bfdf4
parentqa: rsync test: exclude /usr/local (diff)
parentmon: Monitor: tolerate GV duplicates during conversion (diff)
downloadceph-110411630986e083d9012d12a5b6c68b0dcd872c.tar.xz
ceph-110411630986e083d9012d12a5b6c68b0dcd872c.zip
Merge pull request #278 from ceph/wip-4974
Reviewed-by: Greg Farnum <greg@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/mon/Monitor.cc37
-rw-r--r--src/mon/Monitor.h2
2 files changed, 36 insertions, 3 deletions
diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc
index 56cd291cd24..3c40ad38085 100644
--- a/src/mon/Monitor.cc
+++ b/src/mon/Monitor.cc
@@ -4404,23 +4404,54 @@ void Monitor::StoreConverter::_convert_machines(string machine)
dout(20) << __func__ << " " << machine
<< " ver " << ver << " -> " << gv << dendl;
+ MonitorDBStore::Transaction paxos_tx;
+
if (gvs.count(gv) == 0) {
- gvs.insert(gv);
+ gvs.insert(gv);
} else {
dout(0) << __func__ << " " << machine
<< " gv " << gv << " already exists"
<< dendl;
- assert(0 == "Duplicate GV -- something is wrong!");
+
+ // Duplicates aren't supposed to happen, but an old bug introduced
+ // them and the mds state machine wasn't ever trimmed, so many users
+ // will see them. So we'll just merge them all in one
+ // single paxos version.
+ // We know that they are either from another paxos machine or
+ // they are from the same paxos machine but their version is
+ // lower than ours -- given that we are iterating all versions
+ // from the lowest to the highest, duh!
+ // We'll just append our stuff to the existing paxos transaction
+ // as if nothing had happened.
+
+ // Just make sure we are correct. This shouldn't take long and
+ // should never be triggered!
+ set<pair<string,version_t> >& s = gv_map[gv];
+ for (set<pair<string,version_t> >::iterator it = s.begin();
+ it != s.end(); ++it) {
+ if (it->first == machine)
+ assert(it->second + 1 == ver);
+ }
+
+ bufferlist paxos_bl;
+ int r = db->get("paxos", gv, paxos_bl);
+ assert(r >= 0);
+ paxos_tx.append_from_encoded(paxos_bl);
}
+ gv_map[gv].insert(make_pair(machine,ver));
bufferlist tx_bl;
tx.encode(tx_bl);
- tx.put("paxos", gv, tx_bl);
+ paxos_tx.append_from_encoded(tx_bl);
+ bufferlist paxos_bl;
+ paxos_tx.encode(paxos_bl);
+ tx.put("paxos", gv, paxos_bl);
}
db->apply_transaction(tx);
}
version_t lc = db->get(machine, "last_committed");
+ dout(20) << __func__ << " lc " << lc << " last_committed " << last_committed << dendl;
assert(lc == last_committed);
MonitorDBStore::Transaction tx;
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index c06d2fbb54e..57da2aba539 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -1450,6 +1450,8 @@ public:
boost::scoped_ptr<MonitorStore> store;
set<version_t> gvs;
+ map<version_t, set<pair<string,version_t> > > gv_map;
+
version_t highest_last_pn;
version_t highest_accepted_pn;