]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: OSDMonitor: work around a full version bug introduced in 7fb3804fb
authorJoao Eduardo Luis <joao.luis@inktank.com>
Tue, 23 Jul 2013 16:25:13 +0000 (17:25 +0100)
committerSage Weil <sage@inktank.com>
Tue, 23 Jul 2013 16:50:05 +0000 (09:50 -0700)
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>
Reviewed-by: Sage Weil <sage@inktank.com>
(cherry picked from commit 97462a3213e5e15812c79afc0f54d697b6c498b1)

src/mon/OSDMonitor.cc

index 6184f2afe72a0d84948e6c9b2402fa649b046856..7ecb49d296a977911c80b919581290d9ab3221e9 100644 (file)
@@ -126,6 +126,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);