summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-07-26 15:25:12 -0700
committerSage Weil <sage@inktank.com>2013-07-26 15:25:30 -0700
commit6ac8aed040049358aaf8aee5cfb16791c4bb54a2 (patch)
tree9a166ed6acc845659c45e1a6c3b52e7e995c6a51
parent10959404b30aa05c9d416b2a39aaae7d5641389a (diff)
downloadceph-6ac8aed040049358aaf8aee5cfb16791c4bb54a2.tar.gz
mon/PGMonitor: reset in-core PGMap if on-disk format changes
We might have a sequence like: - start mon, load pgmap 100 - sync - including a format upgrade at say v 150 - refresh - see format_version==1, and try read pgmap:101 as new format This simply clears our in-memory state if we see that the format has changed. That will make update_from_paxos reload the latest and prevent it from walking through the old and useless inc updates. Note: this does not affect the auth monitor because we unconditionally load the latest map in update_from_paxos on upgrade. Also, the upgrade there wasn't a format change--just a translation of cap strings from the old to new style. Fixes: #5764 Signed-off-by: Sage Weil <sage@inktank.com> Reviewed-by: Greg Farnum <greg@inktank.com>
-rw-r--r--src/mon/PGMonitor.cc6
-rw-r--r--src/mon/PGMonitor.h1
-rw-r--r--src/mon/PaxosService.cc8
-rw-r--r--src/mon/PaxosService.h5
4 files changed, 19 insertions, 1 deletions
diff --git a/src/mon/PGMonitor.cc b/src/mon/PGMonitor.cc
index 648a8fe2384..d86cbe70c19 100644
--- a/src/mon/PGMonitor.cc
+++ b/src/mon/PGMonitor.cc
@@ -255,6 +255,12 @@ void PGMonitor::update_from_paxos(bool *need_bootstrap)
update_logger();
}
+void PGMonitor::on_upgrade()
+{
+ dout(1) << __func__ << " discarding in-core PGMap" << dendl;
+ pg_map = PGMap();
+}
+
void PGMonitor::upgrade_format()
{
unsigned current = 1;
diff --git a/src/mon/PGMonitor.h b/src/mon/PGMonitor.h
index e8e1b4210aa..44015395e94 100644
--- a/src/mon/PGMonitor.h
+++ b/src/mon/PGMonitor.h
@@ -60,6 +60,7 @@ private:
void create_initial();
void update_from_paxos(bool *need_bootstrap);
void upgrade_format();
+ void on_upgrade();
void post_paxos_update();
void handle_osd_timeouts();
void create_pending(); // prepare a new pending
diff --git a/src/mon/PaxosService.cc b/src/mon/PaxosService.cc
index d6e67a1c4b4..1b21689863b 100644
--- a/src/mon/PaxosService.cc
+++ b/src/mon/PaxosService.cc
@@ -114,7 +114,13 @@ void PaxosService::refresh(bool *need_bootstrap)
// update cached versions
cached_first_committed = mon->store->get(get_service_name(), first_committed_name);
cached_last_committed = mon->store->get(get_service_name(), last_committed_name);
- format_version = get_value("format_version");
+
+ version_t new_format = get_value("format_version");
+ if (new_format != format_version) {
+ dout(1) << __func__ << " upgraded, format " << format_version << " -> " << new_format << dendl;
+ on_upgrade();
+ }
+ format_version = new_format;
dout(10) << __func__ << dendl;
diff --git a/src/mon/PaxosService.h b/src/mon/PaxosService.h
index 74d5a90494c..5321bebcace 100644
--- a/src/mon/PaxosService.h
+++ b/src/mon/PaxosService.h
@@ -459,6 +459,11 @@ public:
virtual void upgrade_format() { }
/**
+ * this is called when we detect the store has just upgraded underneath us
+ */
+ virtual void on_upgrade() {}
+
+ /**
* Called when the Paxos system enters a Leader election.
*
* @remarks It's a courtesy method, in case the class implementing this