summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoao Eduardo Luis <joao.luis@inktank.com>2013-07-23 17:25:13 +0100
committerJoao Eduardo Luis <joao.luis@inktank.com>2013-07-23 17:25:13 +0100
commitf59821dde89aaaf85b429b9523043ff9a679969e (patch)
tree496f7e798cbbf70753a84849db904e467dbd99da
parent55b6546fe5f8c3c86812c1218da9f21019f11604 (diff)
downloadceph-f59821dde89aaaf85b429b9523043ff9a679969e.tar.gz
mon: OSDMonitor: work around a full version bug introduced in 7fb3804fb
In 7fb3804fb860dcd0340dd3f7c39eec4315f8e4b6 we moved the full version stashing logic to the encode_trim_extra() function. However, we forgot to update the osdmap's 'latest_full' key that should always point to the latest osdmap full version. This eventually degenerated in a missing full version after a trim. This patch works around this bug by looking for the latest available full osdmap version in the store and updating 'latest_full' to its proper value. Related-to: #5704 Backport: cuttlefish Signed-off-by: Joao Eduardo Luis <joao.luis@inktank.com>
-rw-r--r--src/mon/OSDMonitor.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc
index 8e5eed13f59..f0b8516d599 100644
--- a/src/mon/OSDMonitor.cc
+++ b/src/mon/OSDMonitor.cc
@@ -125,6 +125,40 @@ void OSDMonitor::update_from_paxos(bool *need_bootstrap)
version_t latest_full = get_version_latest_full();
if (latest_full == 0 && get_first_committed() > 1)
latest_full = get_first_committed();
+
+ if (latest_full < get_first_committed()) {
+ /* a bug introduced in 7fb3804fb860dcd0340dd3f7c39eec4315f8e4b6 would lead
+ * us to not update the on-disk latest_full key. Upon trim, the actual
+ * version would cease to exist but we would still point to it. This
+ * makes sure we get it pointing to a proper version.
+ */
+ version_t lc = get_last_committed();
+ version_t fc = get_first_committed();
+
+ dout(10) << __func__ << " looking for valid full map in interval"
+ << " [" << fc << ", " << lc << "]" << dendl;
+
+ latest_full = 0;
+ for (version_t v = lc; v >= fc; v--) {
+ string full_key = "full_" + stringify(latest_full);
+ if (mon->store->exists(get_service_name(), full_key)) {
+ dout(10) << __func__ << " found latest full map v " << v << dendl;
+ latest_full = v;
+ break;
+ }
+ }
+
+ // if we trigger this, then there's something else going with the store
+ // state, and we shouldn't want to work around it without knowing what
+ // exactly happened.
+ assert(latest_full > 0);
+ MonitorDBStore::Transaction t;
+ put_version_latest_full(&t, latest_full);
+ mon->store->apply_transaction(t);
+ dout(10) << __func__ << " updated the on-disk full map version to "
+ << latest_full << dendl;
+ }
+
if ((latest_full > 0) && (latest_full > osdmap.epoch)) {
bufferlist latest_bl;
get_version_full(latest_full, latest_bl);