diff options
author | Sage Weil <sage@inktank.com> | 2013-05-13 20:39:36 +0200 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-13 20:39:36 +0200 |
commit | 110411630986e083d9012d12a5b6c68b0dcd872c (patch) | |
tree | 7e84a8d7d96f13ff784b0bd1f117386f6c7bfdf4 | |
parent | qa: rsync test: exclude /usr/local (diff) | |
parent | mon: Monitor: tolerate GV duplicates during conversion (diff) | |
download | ceph-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.cc | 37 | ||||
-rw-r--r-- | src/mon/Monitor.h | 2 |
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; |