void mon_info_t::encode(bufferlist& bl, uint64_t features) const
{
- ENCODE_START(2, 1, bl);
+ uint8_t v = 3;
+ if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
+ v = 2;
+ }
+ ENCODE_START(v, 1, bl);
encode(name, bl);
- encode(public_addr, bl, features);
+ if (v < 3) {
+ encode(public_addrs.legacy_addr(), bl, features);
+ } else {
+ encode(public_addrs, bl, features);
+ }
encode(priority, bl);
ENCODE_FINISH(bl);
}
void mon_info_t::decode(bufferlist::const_iterator& p)
{
- DECODE_START(1, p);
+ DECODE_START(3, p);
decode(name, p);
- decode(public_addr, p);
+ decode(public_addrs, p);
if (struct_v >= 2) {
decode(priority, p);
}
void mon_info_t::print(ostream& out) const
{
out << "mon." << name
- << " public " << public_addr
+ << " addrs " << public_addrs
<< " priority " << priority;
}
namespace {
struct rank_cmp {
bool operator()(const mon_info_t &a, const mon_info_t &b) const {
- if (a.public_addr == b.public_addr)
+ if (a.public_addrs.legacy_or_front_addr() == b.public_addrs.legacy_or_front_addr())
return a.name < b.name;
- return a.public_addr < b.public_addr;
+ return a.public_addrs.legacy_or_front_addr() < b.public_addrs.legacy_or_front_addr();
}
};
}
}
map<string,entity_addr_t> legacy_mon_addr;
- for (auto& [name, info] : mon_info) {
- legacy_mon_addr[name] = info.public_addr;
+ if (!HAVE_FEATURE(con_features, MONENC) ||
+ !HAVE_FEATURE(con_features, SERVER_NAUTILUS)) {
+ for (auto& [name, info] : mon_info) {
+ legacy_mon_addr[name] = info.public_addrs.legacy_addr();
+ }
}
- if ((con_features & CEPH_FEATURE_MONENC) == 0) {
+ if (!HAVE_FEATURE(con_features, MONENC)) {
/* we keep the mon_addr map when encoding to ensure compatibility
* with clients and other monitors that do not yet support the 'mons'
* map. This map keeps its original behavior, containing a mapping of
for (auto& [name, addr] : mon_addr) {
mon_info_t &m = mon_info[name];
m.name = name;
- m.public_addr = addr;
+ m.public_addrs = entity_addrvec_t(addr);
}
} else {
decode(mon_info, p);
entity_addr_t local_pub_addr;
local_pub_addr.parse(local_pub_addr_s, &end_p);
- m->add(mon_info_t("filled_pub_addr", local_pub_addr, 1));
+ m->add(mon_info_t("filled_pub_addr", entity_addrvec_t(local_pub_addr), 1));
m->add("empty_addr_zero", entity_addr_t());
}
++p) {
if (has_printed)
out << ",";
- out << p->first << "=" << p->second.public_addr;
+ out << p->first << "=" << p->second.public_addrs;
has_printed = true;
}
out << "}";
for (vector<string>::const_iterator p = ranks.begin();
p != ranks.end();
++p) {
- out << i++ << ": " << get_addr(*p) << " mon." << *p << "\n";
+ out << i++ << ": " << get_addrs(*p) << " mon." << *p << "\n";
}
}
f->open_object_section("mon");
f->dump_int("rank", i);
f->dump_string("name", *p);
- f->dump_stream("addr") << get_addr(*p);
- f->dump_stream("public_addr") << get_addr(*p);
+ f->dump_object("public_addrs", get_addrs(*p));
+ // compat: make these look like pre-nautilus entity_addr_t
+ f->dump_stream("addr") << get_addrs(*p).get_legacy_str();
+ f->dump_stream("public_addr") << get_addrs(*p).get_legacy_str();
f->close_section();
}
f->close_section();
while (i < size()) {
string n = get_name(i);
if (std::find(initial_members.begin(), initial_members.end(), n) != initial_members.end()) {
- lgeneric_dout(cct, 1) << " keeping " << n << " " << get_addr(i) << dendl;
+ lgeneric_dout(cct, 1) << " keeping " << n << " " << get_addrs(i) << dendl;
i++;
continue;
}
- lgeneric_dout(cct, 1) << " removing " << get_name(i) << " " << get_addr(i) << dendl;
- if (removed)
- removed->insert(get_addr(i));
+ lgeneric_dout(cct, 1) << " removing " << get_name(i) << " " << get_addrs(i) << dendl;
+ if (removed) {
+ for (auto& j : get_addrs(i).v) {
+ removed->insert(j);
+ }
+ }
remove(n);
ceph_assert(!contains(n));
}
*/
string name;
/**
- * monitor's public address
+ * monitor's public address(es)
*
- * public facing address, traditionally used to communicate with all clients
- * and other monitors.
+ * public facing address(es), used to communicate with all clients
+ * and with other monitors.
*/
- entity_addr_t public_addr;
+ entity_addrvec_t public_addrs;
/**
* the priority of the mon, the lower value the more preferred
*/
uint16_t priority{0};
+ // <REMOVE ME>
mon_info_t(const string& n, const entity_addr_t& p_addr, uint16_t p)
- : name(n), public_addr(p_addr), priority(p)
+ : name(n), public_addrs(p_addr), priority(p)
{}
- mon_info_t(const string &n, const entity_addr_t& p_addr)
- : name(n), public_addr(p_addr)
+ // </REMOVE ME>
+
+ mon_info_t(const string& n, const entity_addrvec_t& p_addrs, uint16_t p)
+ : name(n), public_addrs(p_addrs), priority(p)
+ {}
+ mon_info_t(const string &n, const entity_addrvec_t& p_addrs)
+ : name(n), public_addrs(p_addrs)
{ }
mon_info_t() { }
// populate addr_mons
addr_mons.clear();
for (auto& p : mon_info) {
- addr_mons[p.second.public_addr] = p.first;
+ for (auto& a : p.second.public_addrs.v) {
+ addr_mons[a] = p.first;
+ }
}
}
* @param ls list to populate with the monitors' addresses
*/
void list_addrs(list<entity_addr_t>& ls) const {
- for (map<string,mon_info_t>::const_iterator p = mon_info.begin();
- p != mon_info.end();
- ++p) {
- ls.push_back(p->second.public_addr);
+ for (auto& i : mon_info) {
+ for (auto& j : i.second.public_addrs.v) {
+ ls.push_back(j);
+ }
}
}
*/
void add(const mon_info_t& m) {
ceph_assert(mon_info.count(m.name) == 0);
- ceph_assert(addr_mons.count(m.public_addr) == 0);
+ for (auto& a : m.public_addrs.v) {
+ ceph_assert(addr_mons.count(a) == 0);
+ }
mon_info[m.name] = m;
if (get_required_features().contains_all(
ceph::features::mon::FEATURE_NAUTILUS)) {
* @param name Monitor name (i.e., 'foo' in 'mon.foo')
* @param addr Monitor's public address
*/
- void add(const string &name, const entity_addr_t &addr) {
- add(mon_info_t(name, addr));
+ void add(const string &name, const entity_addrvec_t &addrv) {
+ add(mon_info_t(name, addrv));
}
/**
* false otherwise.
*/
bool contains(const entity_addr_t &a) const {
- for (map<string,mon_info_t>::const_iterator p = mon_info.begin();
- p != mon_info.end();
- ++p) {
- if (p->second.public_addr == a)
- return true;
+ for (auto& i : mon_info) {
+ for (auto& j : i.second.public_addrs.v) {
+ if (j == a) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ bool contains(const entity_addrvec_t &av) const {
+ for (auto& i : mon_info) {
+ for (auto& j : i.second.public_addrs.v) {
+ for (auto& k : av.v) {
+ if (j == k) {
+ return true;
+ }
+ }
+ }
}
return false;
}
else
return p->second;
}
+ string get_name(const entity_addrvec_t& av) const {
+ for (auto& i : av.v) {
+ map<entity_addr_t,string>::const_iterator p = addr_mons.find(i);
+ if (p != addr_mons.end())
+ return p->second;
+ }
+ return string();
+ }
int get_rank(const string& n) const {
if (auto found = std::find(ranks.begin(), ranks.end(), n);
return true;
}
- entity_addrvec_t get_addrs(const string& n) const {
- return entity_addrvec_t(get_addr(n));
+ // <REMOVE ME>
+ entity_addr_t get_addr(const string& n) const {
+ return get_addrs(n).legacy_addr();
+ }
+ entity_addr_t get_addr(unsigned m) const {
+ return get_addrs(m).legacy_addr();
+ }
+ void set_addr(const string& n, const entity_addr_t& a) {
+ ceph_assert(mon_info.count(n));
+ mon_info[n].public_addrs = entity_addrvec_t(a);
}
- entity_addrvec_t get_addrs(unsigned m) const {
- return entity_addrvec_t(get_addr(m));
+ void add(const string &name, const entity_addr_t &a) {
+ add(name, entity_addrvec_t(a));
}
+ // </REMOVE ME>
- const entity_addr_t& get_addr(const string& n) const {
+ const entity_addrvec_t& get_addrs(const string& n) const {
ceph_assert(mon_info.count(n));
map<string,mon_info_t>::const_iterator p = mon_info.find(n);
- return p->second.public_addr;
+ return p->second.public_addrs;
}
- const entity_addr_t& get_addr(unsigned m) const {
+ const entity_addrvec_t& get_addrs(unsigned m) const {
ceph_assert(m < ranks.size());
- return get_addr(ranks[m]);
+ return get_addrs(ranks[m]);
}
- void set_addr(const string& n, const entity_addr_t& a) {
+ void set_addrvec(const string& n, const entity_addrvec_t& a) {
ceph_assert(mon_info.count(n));
- mon_info[n].public_addr = a;
+ mon_info[n].public_addrs = a;
}
void encode(bufferlist& blist, uint64_t con_features) const;