From 5cba1fb8741391f85087e7ea02d2fdc62d0eaa1a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 21 Dec 2018 07:17:34 -0600 Subject: [PATCH] mon/MonClient: reconnect to mon if it's addrvec appears to have changed This primarily kicks in if we connect to a mon's v1 address during the initial probe and then discover that it has v2+v1. It's a catch-all, though, so that we'll reconnect to the (er, a) mon in any case where we see it's addresses change. Signed-off-by: Sage Weil --- src/mon/MonClient.cc | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index e541e1f1ba7e7..a4948f84a7249 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -348,27 +348,40 @@ void MonClient::flush_log() void MonClient::handle_monmap(MMonMap *m) { ldout(cct, 10) << __func__ << " " << *m << dendl; - auto peer = m->get_source_addr(); - string cur_mon = monmap.get_name(peer); + auto con_addrs = m->get_source_addrs(); + string old_name = monmap.get_name(con_addrs); + // NOTE: we're not paying attention to the epoch, here. auto p = m->monmapbl.cbegin(); decode(monmap, p); ldout(cct, 10) << " got monmap " << monmap.epoch - << ", mon." << cur_mon << " is now rank " << monmap.get_rank(cur_mon) + << " from mon." << old_name + << " (according to old e" << monmap.get_epoch() << ")" << dendl; ldout(cct, 10) << "dump:\n"; monmap.print(*_dout); *_dout << dendl; - sub.got("monmap", monmap.get_epoch()); - - if (!monmap.get_addr_name(peer, cur_mon)) { - ldout(cct, 10) << "mon." << cur_mon << " went away" << dendl; - // can't find the mon we were talking to (above) + if (old_name.size() == 0) { + ldout(cct,10) << " can't identify which mon we were connected to" << dendl; _reopen_session(); + } else { + if (monmap.get_rank(old_name) < 0) { + ldout(cct, 10) << "mon." << old_name << " went away" << dendl; + // can't find the mon we were talking to (above) + _reopen_session(); + } else if (monmap.get_addrs(old_name) != con_addrs) { + // FIXME: we might make this a more sophisticated check later if we do + // multiprotocol IPV4/IPV6 and have a strict preference + ldout(cct,10) << " mon." << old_name << " has addrs " + << monmap.get_addrs(old_name) << " but i'm connected to " + << con_addrs << dendl; + _reopen_session(); + } } + sub.got("monmap", monmap.get_epoch()); map_cond.Signal(); want_monmap = false; } -- 2.39.5