From: Mykola Golub Date: Mon, 6 Jul 2015 08:31:42 +0000 (+0300) Subject: mon: MDSMonitor: keep last_metadata in memory X-Git-Tag: v9.0.3~26^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1883e46fbe755117f646acbb0148381c7e229fd3;p=ceph.git mon: MDSMonitor: keep last_metadata in memory Previously, update_metadata() read last_metadata from the store, added a new metadata to the transaction, and triggered propose, so metadata eventually was updated in the store. But if during this time window another update_metadata() happened, it read old metadata (without the new mds from the first update), and when it was committed the new mds from the first update was lost. Signed-off-by: Mykola Golub --- diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index 7ff52e17749b..0c123c69d3d8 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -138,6 +138,11 @@ void MDSMonitor::update_from_paxos(bool *need_bootstrap) update_logger(); } +void MDSMonitor::init() +{ + (void)load_metadata(pending_metadata); +} + void MDSMonitor::create_pending() { pending_mdsmap = mdsmap; @@ -1757,39 +1762,22 @@ void MDSMonitor::update_metadata(mds_gid_t gid, if (metadata.empty()) { return; } - bufferlist bl; - int err = mon->store->get(MDS_METADATA_PREFIX, "last_metadata", bl); - map last_metadata; - if (!err) { - bufferlist::iterator iter = bl.begin(); - ::decode(last_metadata, iter); - bl.clear(); - } - last_metadata[gid] = metadata; + pending_metadata[gid] = metadata; MonitorDBStore::TransactionRef t = paxos->get_pending_transaction(); - ::encode(last_metadata, bl); + bufferlist bl; + ::encode(pending_metadata, bl); t->put(MDS_METADATA_PREFIX, "last_metadata", bl); paxos->trigger_propose(); } void MDSMonitor::remove_from_metadata(MonitorDBStore::TransactionRef t) { - bufferlist bl; - int err = mon->store->get(MDS_METADATA_PREFIX, "last_metadata", bl); - map last_metadata; - if (err) { - return; - } - bufferlist::iterator iter = bl.begin(); - ::decode(last_metadata, iter); - bl.clear(); - bool update = false; - for (map::iterator i = last_metadata.begin(); - i != last_metadata.end(); ) { + for (map::iterator i = pending_metadata.begin(); + i != pending_metadata.end(); ) { if (pending_mdsmap.get_state_gid(i->first) == MDSMap::STATE_NULL) { - last_metadata.erase(i++); + pending_metadata.erase(i++); update = true; } else { ++i; @@ -1797,7 +1785,8 @@ void MDSMonitor::remove_from_metadata(MonitorDBStore::TransactionRef t) } if (!update) return; - ::encode(last_metadata, bl); + bufferlist bl; + ::encode(pending_metadata, bl); t->put(MDS_METADATA_PREFIX, "last_metadata", bl); } @@ -1857,7 +1846,10 @@ int MDSMonitor::print_nodes(Formatter *f) continue; } const mds_gid_t gid = it->first; - assert(mdsmap.get_state_gid(gid) != MDSMap::STATE_NULL); + if (mdsmap.get_state_gid(gid) == MDSMap::STATE_NULL) { + dout(5) << __func__ << ": GID " << gid << " not existent" << dendl; + continue; + } const MDSMap::mds_info_t& mds_info = mdsmap.get_info_gid(gid); mdses[hostname->second].push_back(mds_info.rank); } diff --git a/src/mon/MDSMonitor.h b/src/mon/MDSMonitor.h index 220da972fc4f..e3d5bd3d5b16 100644 --- a/src/mon/MDSMonitor.h +++ b/src/mon/MDSMonitor.h @@ -74,6 +74,7 @@ class MDSMonitor : public PaxosService { // service methods void create_initial(); void update_from_paxos(bool *need_bootstrap); + void init(); void create_pending(); void encode_pending(MonitorDBStore::TransactionRef t); // we don't require full versions; don't encode any. @@ -147,6 +148,8 @@ private: std::map pending_daemon_health; std::set pending_daemon_health_rm; + map pending_metadata; + int _check_pool(const int64_t pool_id, std::stringstream *ss) const; mds_gid_t gid_from_arg(const std::string& arg, std::ostream& err); };