]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: MDSMonitor: keep last_metadata in memory
authorMykola Golub <mgolub@mirantis.com>
Mon, 6 Jul 2015 08:31:42 +0000 (11:31 +0300)
committerMykola Golub <mgolub@mirantis.com>
Tue, 7 Jul 2015 06:58:34 +0000 (09:58 +0300)
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 <mgolub@mirantis.com>
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h

index 7ff52e17749bf2ab3dd0a338236db2829bad2fdd..0c123c69d3d8e286e7f263a9c58863917f104bfd 100644 (file)
@@ -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<mds_gid_t, Metadata> 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<mds_gid_t, Metadata> last_metadata;
-  if (err) {
-    return;
-  }
-  bufferlist::iterator iter = bl.begin();
-  ::decode(last_metadata, iter);
-  bl.clear();
-
   bool update = false;
-  for (map<mds_gid_t, Metadata>::iterator i = last_metadata.begin();
-       i != last_metadata.end(); ) {
+  for (map<mds_gid_t, Metadata>::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);
   }
index 220da972fc4f446e1475c657ae35f4a970743a01..e3d5bd3d5b165488f76120c1c2bb4e9756464393 100644 (file)
@@ -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<uint64_t, MDSHealth> pending_daemon_health;
   std::set<uint64_t> pending_daemon_health_rm;
 
+  map<mds_gid_t, Metadata> 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);
 };