diff options
-rw-r--r-- | src/mon/MonmapMonitor.cc | 23 | ||||
-rw-r--r-- | src/mon/MonmapMonitor.h | 24 |
2 files changed, 44 insertions, 3 deletions
diff --git a/src/mon/MonmapMonitor.cc b/src/mon/MonmapMonitor.cc index 799f19df154..26fb0dcbb6a 100644 --- a/src/mon/MonmapMonitor.cc +++ b/src/mon/MonmapMonitor.cc @@ -298,12 +298,27 @@ bool MonmapMonitor::prepare_command(MMonCommand *m) addr.set_port(CEPH_MON_PORT); } + do { + if (pending_map.contains(addr)) { + string n = pending_map.get_name(addr); + if (n == name) + break; + } else if (pending_map.contains(name)) + } while (false); + if (pending_map.contains(addr) || pending_map.contains(name)) { - err = -EEXIST; if (!ss.str().empty()) ss << "; "; - ss << "mon " << name << " " << addr << " already exists"; + + string n = pending_map.get_name(addr); + if (n == name) { + err = 0; + ss << "added mon." << name << " at " << addr; + } else { + err = -EEXIST; + ss << "mon." << name << " at " << addr << " already exists"; + } goto out; } @@ -311,7 +326,9 @@ bool MonmapMonitor::prepare_command(MMonCommand *m) pending_map.last_changed = ceph_clock_now(g_ceph_context); ss << "added mon." << name << " at " << addr; getline(ss, rs); - wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs, get_last_committed())); + wait_for_finished_proposal(new C_MonmapCommand(mon, m, 0, rs, + get_last_committed(), + pending_map.last_changed)); return true; } else if (prefix == "mon remove") { diff --git a/src/mon/MonmapMonitor.h b/src/mon/MonmapMonitor.h index 198489d7017..a0fccfd56f2 100644 --- a/src/mon/MonmapMonitor.h +++ b/src/mon/MonmapMonitor.h @@ -30,6 +30,7 @@ using namespace std; #include "PaxosService.h" #include "MonMap.h" #include "MonitorDBStore.h" +#include "Monitor.h" class MMonGetMap; class MMonMap; @@ -81,6 +82,29 @@ class MonmapMonitor : public PaxosService { void tick(); + struct C_MonmapCommand : public Monitor::C_Command { + utime_t last_changed; + + C_MonmapCommand(Monitor *_mon, MMonCommand *_m, int r, + string s, version_t v, utime_t changed) : + Monitor::C_Command(_mon, _m, r, s, v), + last_changed(changed) + { } + + void finish(int r) { + int ret = r; + if (r == -EAGAIN) { + MonMap m; + mon->monmon()->get_monmap(m); + if ((m.get_epoch() == version+1) + && (m.last_changed == last_changed)) { + ret = 0; + } + } + Monitor::C_Command::finish(ret); + } + }; + private: bufferlist monmap_bl; }; |