Because now we have quorum_mon_features too.
Signed-off-by: Joao Eduardo Luis <joao@suse.de>
::encode(v, bl);
vector<Incremental>::iterator p;
for (p = pending_auth.begin(); p != pending_auth.end(); ++p)
- p->encode(bl, mon->get_quorum_features());
+ p->encode(bl, mon->get_quorum_con_features());
version_t version = get_last_committed() + 1;
put_version(t, version, bl);
::encode(v, bl);
multimap<utime_t,LogEntry>::iterator p;
for (p = pending_log.begin(); p != pending_log.end(); ++p)
- p->second.encode(bl, mon->quorum_features);
+ p->second.encode(bl, mon->get_quorum_con_features());
put_version(t, version, bl);
put_last_committed(t, version);
assert(get_last_committed() == summary.version);
bufferlist summary_bl;
- ::encode(summary, summary_bl, mon->quorum_features);
+ ::encode(summary, summary_bl, mon->get_quorum_con_features());
put_version_full(t, summary.version, summary_bl);
put_version_latest_full(t, summary.version);
fs->mds_map.session_timeout = g_conf->mds_session_timeout;
fs->mds_map.session_autoclose = g_conf->mds_session_autoclose;
fs->mds_map.enabled = true;
- if (mon->get_quorum_features() & CEPH_FEATURE_SERVER_JEWEL) {
+ if (mon->get_quorum_con_features() & CEPH_FEATURE_SERVER_JEWEL) {
fs->fscid = fsm.next_filesystem_id++;
// ANONYMOUS is only for upgrades from legacy mdsmaps, we should
// have initialized next_filesystem_id such that it's never used here.
// apply to paxos
assert(get_last_committed() + 1 == pending_fsmap.epoch);
bufferlist fsmap_bl;
- pending_fsmap.encode(fsmap_bl, mon->get_quorum_features());
+ pending_fsmap.encode(fsmap_bl, mon->get_quorum_con_features());
/* put everything in the transaction */
put_version(t, pending_fsmap.epoch, fsmap_bl);
return r;
}
- bool jewel = mon->get_quorum_features() & CEPH_FEATURE_SERVER_JEWEL;
+ bool jewel = mon->get_quorum_con_features() && CEPH_FEATURE_SERVER_JEWEL;
if (flag_bool && !jewel) {
ss << "Multiple-filesystems are forbidden until all mons are updated";
return -EINVAL;
using ceph::Formatter;
-void MonMap::encode(bufferlist& blist, uint64_t features) const
+void MonMap::encode(bufferlist& blist, uint64_t con_features) const
{
- if ((features & CEPH_FEATURE_MONNAMES) == 0) {
+ if ((con_features & CEPH_FEATURE_MONNAMES) == 0) {
__u16 v = 1;
::encode(v, blist);
::encode_raw(fsid, blist);
vector<entity_inst_t> mon_inst(mon_addr.size());
for (unsigned n = 0; n < mon_addr.size(); n++)
mon_inst[n] = get_inst(n);
- ::encode(mon_inst, blist, features);
+ ::encode(mon_inst, blist, con_features);
::encode(last_changed, blist);
::encode(created, blist);
return;
}
- if ((features & CEPH_FEATURE_MONENC) == 0) {
+ if ((con_features & CEPH_FEATURE_MONENC) == 0) {
__u16 v = 2;
::encode(v, blist);
::encode_raw(fsid, blist);
::encode(epoch, blist);
- ::encode(mon_addr, blist, features);
+ ::encode(mon_addr, blist, con_features);
::encode(last_changed, blist);
::encode(created, blist);
}
- ENCODE_START(3, 3, blist);
+ ENCODE_START(4, 3, blist);
::encode_raw(fsid, blist);
::encode(epoch, blist);
- ::encode(mon_addr, blist, features);
+ ::encode(mon_addr, blist, con_features);
::encode(last_changed, blist);
::encode(created, blist);
+ ::encode(persistent_features, blist);
+ ::encode(optional_features, blist);
ENCODE_FINISH(blist);
}
void MonMap::decode(bufferlist::iterator &p)
{
- DECODE_START_LEGACY_COMPAT_LEN_16(3, 3, 3, p);
+ DECODE_START_LEGACY_COMPAT_LEN_16(4, 3, 3, p);
::decode_raw(fsid, p);
::decode(epoch, p);
if (struct_v == 1) {
}
::decode(last_changed, p);
::decode(created, p);
+ if (struct_v >= 4) {
+ ::decode(persistent_features, p);
+ ::decode(optional_features, p);
+ }
+
DECODE_FINISH(p);
calc_ranks();
}
f->dump_stream("fsid") << fsid;
f->dump_stream("modified") << last_changed;
f->dump_stream("created") << created;
+ f->open_object_section("features");
+ persistent_features.dump(f, "persistent");
+ optional_features.dump(f, "optional");
+ f->close_section();
f->open_array_section("mons");
int i = 0;
for (map<entity_addr_t,string>::const_iterator p = addr_name.begin();
#include "msg/Message.h"
#include "include/types.h"
+#include "mon/mon_types.h"
namespace ceph {
class Formatter;
}
+
class MonMap {
public:
epoch_t epoch; // what epoch/version of the monmap
vector<string> rank_name;
vector<entity_addr_t> rank_addr;
+ /**
+ * Persistent Features are all those features that once set on a
+ * monmap cannot, and should not, be removed. These will define the
+ * non-negotiable features that a given monitor must support to
+ * properly operate in a given quorum.
+ *
+ * Should be reserved for features that we really want to make sure
+ * are sticky, and are important enough to tolerate not being able
+ * to downgrade a monitor.
+ */
+ mon_feature_t persistent_features;
+ /**
+ * Optional Features are all those features that can be enabled or
+ * disabled following a given criteria -- e.g., user-mandated via the
+ * cli --, and act much like indicators of what the cluster currently
+ * supports.
+ *
+ * They are by no means "optional" in the sense that monitors can
+ * ignore them. Just that they are not persistent.
+ */
+ mon_feature_t optional_features;
+
+ /**
+ * Returns the set of features required by this monmap.
+ *
+ * The features required by this monmap is the union of all the
+ * currently set persistent features and the currently set optional
+ * features.
+ *
+ * @returns the set of features required by this monmap
+ */
+ mon_feature_t get_required_features() const {
+ return (persistent_features | optional_features);
+ }
+
void calc_ranks() {
rank_name.resize(mon_addr.size());
rank_addr.resize(mon_addr.size());
}
}
- MonMap()
+ MonMap()
: epoch(0) {
memset(&fsid, 0, sizeof(fsid));
}
mon_addr[name] = addr;
calc_ranks();
}
-
+
void remove(const string &name) {
assert(mon_addr.count(name));
mon_addr.erase(name);
return i;
}
- void encode(bufferlist& blist, uint64_t features) const;
+ void encode(bufferlist& blist, uint64_t con_features) const;
void decode(bufferlist& blist) {
bufferlist::iterator p = blist.begin();
decode(p);
elector(this),
required_features(0),
leader(0),
- quorum_features(0),
+ quorum_con_features(0),
// scrub
scrub_version(0),
scrub_event(NULL),
leader_since = ceph_clock_now(g_ceph_context);
leader = rank;
quorum = active;
- quorum_features = features;
+ quorum_con_features = features;
quorum_mon_features = mon_features;
outside_quorum.clear();
leader = l;
quorum = q;
outside_quorum.clear();
- quorum_features = features;
+ quorum_con_features = features;
quorum_mon_features = mon_features;
dout(10) << "lose_election, epoch " << epoch << " leader is mon" << leader
- << " quorum is " << quorum << " features are " << quorum_features
+ << " quorum is " << quorum << " features are " << quorum_con_features
<< " mon_features are " << quorum_mon_features
<< dendl;
finish_election();
- if (quorum_features & CEPH_FEATURE_MON_METADATA) {
+ if (quorum_con_features & CEPH_FEATURE_MON_METADATA) {
Metadata sys_info;
collect_sys_info(&sys_info, g_ceph_context);
messenger->send_message(new MMonMetadata(sys_info),
void Monitor::apply_quorum_to_compatset_features()
{
CompatSet new_features(features);
- if (quorum_features & CEPH_FEATURE_OSD_ERASURE_CODES) {
+ if (quorum_con_features & CEPH_FEATURE_OSD_ERASURE_CODES) {
new_features.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_OSD_ERASURE_CODES);
}
- if (quorum_features & CEPH_FEATURE_OSDMAP_ENC) {
+ if (quorum_con_features & CEPH_FEATURE_OSDMAP_ENC) {
new_features.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_OSDMAP_ENC);
}
- if (quorum_features & CEPH_FEATURE_ERASURE_CODE_PLUGINS_V2) {
+ if (quorum_con_features & CEPH_FEATURE_ERASURE_CODE_PLUGINS_V2) {
new_features.incompat.insert(CEPH_MON_FEATURE_INCOMPAT_ERASURE_CODE_PLUGINS_V2);
}
- if (quorum_features & CEPH_FEATURE_ERASURE_CODE_PLUGINS_V3) {
+ 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) {
dout(10) << "try_send_message " << *m << " to " << to << dendl;
bufferlist bl;
- encode_message(m, quorum_features, bl);
+ encode_message(m, quorum_con_features, bl);
messenger->send_message(m, to);
set<int> quorum; // current active set of monitors (if !starting)
utime_t leader_since; // when this monitor became the leader, if it is the leader
utime_t exited_quorum; // time detected as not in quorum; 0 if in
- uint64_t quorum_features; ///< intersection of quorum member feature bits
+ /**
+ * Intersection of quorum member's connection feature bits.
+ */
+ uint64_t quorum_con_features;
/**
* Intersection of quorum members mon-specific feature bits
*/
q.push_back(monmap->get_name(*p));
return q;
}
- uint64_t get_quorum_features() const {
- return quorum_features;
+ uint64_t get_quorum_con_features() const {
+ return quorum_con_features;
}
uint64_t get_required_features() const {
return required_features;
assert(mon->monmap->epoch + 1 == pending_map.epoch ||
pending_map.epoch == 1); // special case mkfs!
bufferlist bl;
- pending_map.encode(bl, mon->get_quorum_features());
+ pending_map.encode(bl, mon->get_quorum_con_features());
put_version(t, pending_map.epoch, bl);
put_last_committed(t, pending_map.epoch);
newmap.set_flag(CEPH_OSDMAP_REQUIRE_KRAKEN);
// encode into pending incremental
- newmap.encode(pending_inc.fullmap, mon->quorum_features | CEPH_FEATURE_RESERVED);
+ newmap.encode(pending_inc.fullmap,
+ mon->get_quorum_con_features() | CEPH_FEATURE_RESERVED);
pending_inc.full_crc = newmap.get_crc();
dout(20) << " full crc " << pending_inc.full_crc << dendl;
}
// encode with all features.
uint64_t f = inc.encode_features;
if (!f)
- f = mon->quorum_features;
+ f = mon->get_quorum_con_features();
if (!f)
f = -1;
bufferlist full_bl;
}
// features for osdmap and its incremental
- uint64_t features = mon->quorum_features;
+ uint64_t features = mon->get_quorum_con_features();
// encode full map and determine its crc
OSDMap tmp;
{
stringstream unsupported_ss;
int unsupported_count = 0;
- if ((mon->get_quorum_features() & features) != features) {
+ if ((mon->get_quorum_con_features() & features) != features) {
unsupported_ss << "the monitor cluster";
++unsupported_count;
}
assert(get_last_committed() + 1 == version);
pending_inc.stamp = ceph_clock_now(g_ceph_context);
- uint64_t features = mon->get_quorum_features();
+ uint64_t features = mon->get_quorum_con_features();
string prefix = pgmap_meta_prefix;