From aa0ea88fd02e25cdd4ba217ab7dc8094ef4e1b10 Mon Sep 17 00:00:00 2001 From: Joao Eduardo Luis Date: Sun, 7 Feb 2016 19:09:06 +0000 Subject: [PATCH] mon: don't allow downgrading once we go the kraken way Otherwise monitors - downgraded monitors - will not honour the monmap features required to form quorum. Signed-off-by: Joao Eduardo Luis --- src/mon/Monitor.cc | 55 ++++++++++++++++++++++++++++++++++++++-------- src/mon/Monitor.h | 4 ++++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index a6c64ab1f0ee9..c3f18e3005f6d 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -379,6 +379,7 @@ CompatSet Monitor::get_supported_features() compat.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_OSDMAP_ENC); compat.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V2); compat.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V3); + compat.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_KRAKEN); return compat; } @@ -1964,6 +1965,7 @@ void Monitor::lose_election(epoch_t epoch, set &q, int l, void Monitor::finish_election() { apply_quorum_to_compatset_features(); + apply_monmap_to_compatset_features(); timecheck_finish(); exited_quorum = utime_t(); finish_contexts(g_ceph_context, waitfor_quorum); @@ -1981,6 +1983,21 @@ void Monitor::finish_election() } } +void Monitor::_apply_compatset_features(CompatSet &new_features) +{ + if (new_features.compare(features) != 0) { + CompatSet diff = features.unsupported(new_features); + dout(1) << __func__ << " enabling new quorum features: " << diff << dendl; + features = new_features; + + auto t = std::make_shared(); + write_features(t); + store->apply_transaction(t); + + apply_compatset_features_to_quorum_requirements(); + } +} + void Monitor::apply_quorum_to_compatset_features() { CompatSet new_features(features); @@ -1996,17 +2013,34 @@ void Monitor::apply_quorum_to_compatset_features() if (quorum_con_features & CEPH_FEATURE_ERASURE_CODE_PLUGINS_V3) { new_features.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V3); } - if (new_features.compare(features) != 0) { - CompatSet diff = features.unsupported(new_features); - dout(1) << __func__ << " enabling new quorum features: " << diff << dendl; - features = new_features; - - MonitorDBStore::TransactionRef t(new MonitorDBStore::Transaction); - write_features(t); - store->apply_transaction(t); + dout(5) << __func__ << dendl; + _apply_compatset_features(new_features); +} - apply_compatset_features_to_quorum_requirements(); +void Monitor::apply_monmap_to_compatset_features() +{ + CompatSet new_features(features); + mon_feature_t monmap_features = monmap->get_required_features(); + + /* persistent monmap features may go into the compatset. + * optional monmap features may not - why? + * because optional monmap features may be set/unset by the admin, + * and possibly by other means that haven't yet been thought out, + * so we can't make the monitor enforce them on start - because they + * may go away. + * this, of course, does not invalidate setting a compatset feature + * for an optional feature - as long as you make sure to clean it up + * once you unset it. + */ + if (monmap_features.contains_all(ceph::features::mon::FEATURE_KRAKEN)) { + assert(ceph::features::mon::get_persistent().contains_all( + ceph::features::mon::FEATURE_KRAKEN)); + // this feature should only ever be set if the quorum supports it. + assert(quorum_con_features & CEPH_FEATURE_SERVER_KRAKEN); + new_features.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_KRAKEN); } + dout(5) << __func__ << dendl; + _apply_compatset_features(new_features); } void Monitor::apply_compatset_features_to_quorum_requirements() @@ -2024,6 +2058,9 @@ void Monitor::apply_compatset_features_to_quorum_requirements() if (features.incompat.contains(CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V3)) { required_features |= CEPH_FEATURE_ERASURE_CODE_PLUGINS_V3; } + if (features.incompat.contains(CEPH_MON_FEATURE_INCOMPAT_KRAKEN)) { + required_features |= CEPH_FEATURE_SERVER_KRAKEN; + } dout(10) << __func__ << " required_features " << required_features << dendl; } diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 29a04f6c07e87..8096be792e4b2 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -577,6 +577,8 @@ private: void cancel_probe_timeout(); void probe_timeout(int r); + void _apply_compatset_features(CompatSet &new_features); + public: epoch_t get_epoch(); int get_leader() { return leader; } @@ -600,6 +602,7 @@ public: return monmap->get_required_features(); } void apply_quorum_to_compatset_features(); + void apply_monmap_to_compatset_features(); void apply_compatset_features_to_quorum_requirements(); private: @@ -992,6 +995,7 @@ public: #define CEPH_MON_FEATURE_INCOMPAT_OSDMAP_ENC CompatSet::Feature(5, "new-style osdmap encoding") #define CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V2 CompatSet::Feature(6, "support isa/lrc erasure code") #define CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V3 CompatSet::Feature(7, "support shec erasure code") +#define CEPH_MON_FEATURE_INCOMPAT_KRAKEN CompatSet::Feature(8, "support monmap features") // make sure you add your feature to Monitor::get_supported_features long parse_pos_long(const char *s, ostream *pss = NULL); -- 2.39.5