class MMonProbe : public Message {
public:
- static const int HEAD_VERSION = 5;
+ static const int HEAD_VERSION = 6;
static const int COMPAT_VERSION = 5;
enum {
OP_SLURP = 3,
OP_SLURP_LATEST = 4,
OP_DATA = 5,
+ OP_MISSING_FEATURES = 6,
};
static const char *get_opname(int o) {
case OP_SLURP: return "slurp";
case OP_SLURP_LATEST: return "slurp_latest";
case OP_DATA: return "data";
+ case OP_MISSING_FEATURES: return "missing_features";
default: assert(0); return 0;
}
}
version_t paxos_first_version;
version_t paxos_last_version;
bool has_ever_joined;
+ uint64_t required_features;
MMonProbe()
: Message(MSG_MON_PROBE, HEAD_VERSION, COMPAT_VERSION) {}
name(n),
paxos_first_version(0),
paxos_last_version(0),
- has_ever_joined(hej) {}
+ has_ever_joined(hej),
+ required_features(0) {}
private:
~MMonProbe() {}
}
if (!has_ever_joined)
out << " new";
+ if (required_features)
+ out << " required_features " << required_features;
out << ")";
}
::encode(has_ever_joined, payload);
::encode(paxos_first_version, payload);
::encode(paxos_last_version, payload);
+ ::encode(required_features, payload);
}
void decode_payload() {
bufferlist::iterator p = payload.begin();
::decode(has_ever_joined, p);
::decode(paxos_first_version, p);
::decode(paxos_last_version, p);
+ if (header.version >= 6)
+ ::decode(required_features, p);
+ else
+ required_features = 0;
}
};
handle_probe_reply(m);
break;
+ case MMonProbe::OP_MISSING_FEATURES:
+ derr << __func__ << " missing features, have " << CEPH_FEATURES_ALL
+ << ", required " << required_features
+ << ", missing " << (required_features & ~CEPH_FEATURES_ALL)
+ << dendl;
+ break;
+
default:
m->put();
}
*/
void Monitor::handle_probe_probe(MMonProbe *m)
{
- dout(10) << "handle_probe_probe " << m->get_source_inst() << *m << dendl;
- MMonProbe *r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY, name, has_ever_joined);
+ 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->get_connection()->has_feature(CEPH_FEATURE_OSD_PRIMARY_AFFINITY)) {
+ MMonProbe *r = new MMonProbe(monmap->fsid, MMonProbe::OP_MISSING_FEATURES,
+ name, has_ever_joined);
+ m->required_features = required_features;
+ messenger->send_message(r, m->get_connection());
+ }
+ m->put();
+ return;
+ }
+
+ MMonProbe *r = new MMonProbe(monmap->fsid, MMonProbe::OP_REPLY,
+ name, has_ever_joined);
r->name = name;
r->quorum = quorum;
monmap->encode(r->monmap_bl, m->get_connection()->get_features());
// did we discover a peer here?
if (!monmap->contains(m->get_source_addr())) {
- dout(1) << " adding peer " << m->get_source_addr() << " to list of hints" << dendl;
+ dout(1) << " adding peer " << m->get_source_addr()
+ << " to list of hints" << dendl;
extra_probe_peers.insert(m->get_source_addr());
}
+
m->put();
}