diff options
author | Sage Weil <sage@inktank.com> | 2013-07-26 15:25:12 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-07-26 15:25:30 -0700 |
commit | 6ac8aed040049358aaf8aee5cfb16791c4bb54a2 (patch) | |
tree | 9a166ed6acc845659c45e1a6c3b52e7e995c6a51 | |
parent | 10959404b30aa05c9d416b2a39aaae7d5641389a (diff) | |
download | ceph-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.cc | 6 | ||||
-rw-r--r-- | src/mon/PGMonitor.h | 1 | ||||
-rw-r--r-- | src/mon/PaxosService.cc | 8 | ||||
-rw-r--r-- | src/mon/PaxosService.h | 5 |
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 |