From: Joao Eduardo Luis Date: Sat, 12 Jan 2013 01:06:36 +0000 (+0000) Subject: mon: OSDMonitor: only share osdmap with up OSDs X-Git-Tag: v0.56.2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=95677fc599b9bf37ab4c2037b3675fd68f92ebcf;p=ceph.git mon: OSDMonitor: only share osdmap with up OSDs Try to share the map with a randomly picked OSD; if the picked monitor is not 'up', then try to find the nearest 'up' OSD in the map by doing a backward and a forward linear search on the map -- this would be O(n) in the worst case scenario, as we only do a single iteration starting on the picked position, incrementing and decrementing two different iterators until we find an appropriate OSD or we exhaust the map. Fixes: #3629 Backport: bobtail Signed-off-by: Joao Eduardo Luis Reviewed-by: Sage Weil (cherry picked from commit 3610e72e4f9117af712f34a2e12c5e9537a5746f) --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 2cc352751efe..9845552fc00c 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -461,13 +461,21 @@ void OSDMonitor::encode_pending(bufferlist &bl) void OSDMonitor::share_map_with_random_osd() { - // tell any osd - MonSession *s = mon->session_map.get_random_osd_session(); - if (s) { - dout(10) << "committed, telling random " << s->inst << " all about it" << dendl; - MOSDMap *m = build_incremental(osdmap.get_epoch() - 1, osdmap.get_epoch()); // whatev, they'll request more if they need it - mon->messenger->send_message(m, s->inst); + if (osdmap.get_num_up_osds() == 0) { + dout(10) << __func__ << " no up osds, don't share with anyone" << dendl; + return; } + + MonSession *s = mon->session_map.get_random_osd_session(&osdmap); + if (!s) { + dout(10) << __func__ << " no up osd on our session map" << dendl; + return; + } + + dout(10) << "committed, telling random " << s->inst << " all about it" << dendl; + // whatev, they'll request more if they need it + MOSDMap *m = build_incremental(osdmap.get_epoch() - 1, osdmap.get_epoch()); + mon->messenger->send_message(m, s->inst); } diff --git a/src/mon/Session.h b/src/mon/Session.h index edf5d66ef6fa..bbdc3e50615c 100644 --- a/src/mon/Session.h +++ b/src/mon/Session.h @@ -19,6 +19,7 @@ #include "msg/msg_types.h" #include "auth/AuthServiceHandler.h" +#include "osd/OSDMap.h" #include "MonCaps.h" @@ -118,19 +119,50 @@ struct MonSessionMap { s->get(); // caller gets a ref return s; } - - MonSession *get_random_osd_session() { + + MonSession *get_random_osd_session(OSDMap *osdmap) { // ok, this isn't actually random, but close enough. if (by_osd.empty()) return 0; int n = by_osd.rbegin()->first + 1; int r = rand() % n; + multimap::iterator p = by_osd.lower_bound(r); if (p == by_osd.end()) p--; - return p->second; - } + if (!osdmap) { + return p->second; + } + + MonSession *s = NULL; + + multimap::iterator b = p, f = p; + bool backward = true, forward = true; + while (backward || forward) { + if (backward) { + if (osdmap->is_up(b->first)) { + s = b->second; + break; + } + if (b != by_osd.begin()) + --b; + else + backward = false; + } + + forward = (f != by_osd.end()); + if (forward) { + if (osdmap->is_up(f->first)) { + s = f->second; + break; + } + ++f; + } + } + + return s; + } void add_update_sub(MonSession *s, const string& what, version_t start, bool onetime, bool incremental_onetime) { Subscription *sub = 0;