public:
friend factory;
- static constexpr int HEAD_VERSION = 6;
+ static constexpr int HEAD_VERSION = 7;
static constexpr int COMPAT_VERSION = 5;
enum {
version_t paxos_last_version = 0;
bool has_ever_joined = 0;
uint64_t required_features = 0;
+ uint8_t mon_release = 0;
MMonProbe()
: MessageInstance(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION) {}
- MMonProbe(const uuid_d& f, int o, const string& n, bool hej)
+ MMonProbe(const uuid_d& f, int o, const string& n, bool hej, uint8_t mr)
: MessageInstance(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION),
fsid(f),
op(o),
paxos_first_version(0),
paxos_last_version(0),
has_ever_joined(hej),
- required_features(0) {}
+ required_features(0),
+ mon_release(mr) {}
private:
~MMonProbe() override {}
out << " new";
if (required_features)
out << " required_features " << required_features;
+ if (mon_release)
+ out << " mon_release " << (int)mon_release;
out << ")";
}
encode(paxos_first_version, payload);
encode(paxos_last_version, payload);
encode(required_features, payload);
+ encode(mon_release, payload);
}
void decode_payload() override {
auto p = payload.cbegin();
decode(required_features, p);
else
required_features = 0;
+ if (header.version >= 7)
+ decode(mon_release, p);
+ else
+ mon_release = 0;
}
};
for (unsigned i = 0; i < monmap->size(); i++) {
if ((int)i != rank)
send_mon_message(
- new MMonProbe(monmap->fsid, MMonProbe::OP_PROBE, name, has_ever_joined),
+ new MMonProbe(monmap->fsid, MMonProbe::OP_PROBE, name, has_ever_joined,
+ ceph_release()),
i);
}
for (auto& av : extra_probe_peers) {
if (av != messenger->get_myaddrs()) {
messenger->send_to_mon(
- new MMonProbe(monmap->fsid, MMonProbe::OP_PROBE, name, has_ever_joined),
+ new MMonProbe(monmap->fsid, MMonProbe::OP_PROBE, name, has_ever_joined,
+ ceph_release()),
av);
}
}
break;
case MMonProbe::OP_MISSING_FEATURES:
- derr << __func__ << " missing features, have " << CEPH_FEATURES_ALL
+ derr << __func__ << " require release " << m->mon_release << " > "
+ << ceph_release() << ", or missing features (have " << CEPH_FEATURES_ALL
<< ", required " << m->required_features
- << ", missing " << (m->required_features & ~CEPH_FEATURES_ALL)
+ << ", missing " << (m->required_features & ~CEPH_FEATURES_ALL) << ")"
<< dendl;
break;
}
dout(10) << "handle_probe_probe " << m->get_source_inst() << *m
<< " features " << m->get_connection()->get_features() << dendl;
uint64_t missing = required_features & ~m->get_connection()->get_features();
- if (missing) {
- dout(1) << " peer " << m->get_source_addr() << " missing features "
- << missing << dendl;
+ if (m->mon_release < monmap->min_mon_release || missing) {
+ dout(1) << " peer " << m->get_source_addr() << " release " << m->mon_release
+ << " < min_mon_release " << monmap->min_mon_release
+ << ", or missing features " << missing << dendl;
MMonProbe *r = new MMonProbe(monmap->fsid, MMonProbe::OP_MISSING_FEATURES,
- name, has_ever_joined);
+ name, has_ever_joined, monmap->min_mon_release);
m->required_features = required_features;
m->get_connection()->send_message(r);
goto out;
}
MMonProbe *r;
- r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY, name, has_ever_joined);
+ r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY, name, has_ever_joined,
+ ceph_release());
r->name = name;
r->quorum = quorum;
monmap->encode(r->monmap_bl, m->get_connection()->get_features());
#include "global/global_init.h"
#include "global/global_context.h"
#include "common/ceph_argparse.h"
+#include "common/version.h"
#include "common/dout.h"
#include "common/debug.h"
#include "common/Cond.h"
TEST_F(MonMsgTest, MMonProbeTest)
{
Message *m = new MMonProbe(get_monmap()->fsid,
- MMonProbe::OP_PROBE, "b", false);
+ MMonProbe::OP_PROBE, "b", false,
+ ceph_release());
Message *r = send_wait_reply(m, MSG_MON_PROBE);
ASSERT_NE(IS_ERR(r), 0);
ASSERT_EQ(PTR_ERR(r), -ETIMEDOUT);