From: Sage Weil Date: Fri, 26 Jul 2013 22:25:12 +0000 (-0700) Subject: mon/PGMonitor: reset in-core PGMap if on-disk format changes X-Git-Tag: v0.67-rc3~40 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=6ac8aed040049358aaf8aee5cfb16791c4bb54a2;p=ceph.git 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 Reviewed-by: Greg Farnum --- diff --git a/src/mon/PGMonitor.cc b/src/mon/PGMonitor.cc index 648a8fe238466..d86cbe70c19fd 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 e8e1b4210aaaa..44015395e943e 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 d6e67a1c4b4c0..1b21689863bc6 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 74d5a90494c87..5321bebcacefc 100644 --- a/src/mon/PaxosService.h +++ b/src/mon/PaxosService.h @@ -458,6 +458,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. *