]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: request daemon's metadata when receiving a report message from an unknown server 18484/head
authorChang Liu <liuchang0812@gmail.com>
Sat, 21 Oct 2017 15:35:47 +0000 (23:35 +0800)
committerChang Liu <liuchang0812@gmail.com>
Thu, 16 Nov 2017 03:29:46 +0000 (11:29 +0800)
Fixes: http://tracker.ceph.com/issues/21687
Signed-off-by: Chang Liu <liuchang0812@gmail.com>
src/mgr/DaemonServer.cc
src/mgr/Mgr.cc
src/mgr/Mgr.h

index bdb3cc96a7c1d80f4dc50c63f83ab7aef27c100b..450c0059c0c99906092d7073102a45c0b402a8f7 100644 (file)
@@ -12,7 +12,9 @@
  */
 
 #include "DaemonServer.h"
+#include "mgr/Mgr.h"
 
+#include "include/stringify.h"
 #include "include/str_list.h"
 #include "auth/RotatingKeyRing.h"
 #include "json_spirit/json_spirit_writer.h"
@@ -418,15 +420,53 @@ bool DaemonServer::handle_report(MMgrReport *m)
     daemon = daemon_state.get(key);
   } else {
     // we don't know the hostname at this stage, reject MMgrReport here.
-    dout(1) << "rejecting report from " << key << ", since we do not have its metadata now."
+    dout(5) << "rejecting report from " << key << ", since we do not have its metadata now."
            << dendl;
-    // kill session
-    MgrSessionRef session(static_cast<MgrSession*>(m->get_connection()->get_priv()));
-    if (!session) {
-      return false;
+
+    // issue metadata request in background
+    if (!daemon_state.is_updating(key) && 
+       (key.first == "osd" || key.first == "mds")) {
+
+      std::ostringstream oss;
+      auto c = new MetadataUpdate(daemon_state, key);
+      if (key.first == "osd") {
+        oss << "{\"prefix\": \"osd metadata\", \"id\": "
+            << key.second<< "}";
+
+      } else if (key.first == "mds") {
+        c->set_default("addr", stringify(m->get_source_addr()));
+        oss << "{\"prefix\": \"mds metadata\", \"who\": \""
+            << key.second << "\"}";
+      } else {
+       ceph_abort();
+      }
+
+      monc->start_mon_command({oss.str()}, {}, &c->outbl, &c->outs, c);
+    }
+    
+    {
+      Mutex::Locker l(lock);
+      // kill session
+      MgrSessionRef session(static_cast<MgrSession*>(m->get_connection()->get_priv()));
+      if (!session) {
+       return false;
+      }
+      m->get_connection()->mark_down();
+      session->put();
+
+      dout(10) << "unregistering osd." << session->osd_id
+              << "  session " << session << " con " << m->get_connection() << dendl;
+      
+      if (osd_cons.find(session->osd_id) != osd_cons.end()) {
+          osd_cons[session->osd_id].erase(m->get_connection());
+      } 
+
+      auto iter = daemon_connections.find(m->get_connection());
+      if (iter != daemon_connections.end()) {
+       daemon_connections.erase(iter);
+      }
     }
-    m->get_connection()->mark_down();
-    session->put();
 
     return false;
   }
index de60b4c771fa95bffdd43c936e2643d78aa8b603..e359aee7f229d1d5473d13d3c3f5ccb4c8e463f4 100644 (file)
@@ -68,98 +68,72 @@ Mgr::~Mgr()
 {
 }
 
-
-/**
- * Context for completion of metadata mon commands: take
- * the result and stash it in DaemonStateIndex
- */
-class MetadataUpdate : public Context
+void MetadataUpdate::finish(int r)
 {
-  DaemonStateIndex &daemon_state;
-  DaemonKey key;
-
-  std::map<std::string, std::string> defaults;
-
-public:
-  bufferlist outbl;
-  std::string outs;
-
-  MetadataUpdate(DaemonStateIndex &daemon_state_, const DaemonKey &key_)
-    : daemon_state(daemon_state_), key(key_) {}
-
-  void set_default(const std::string &k, const std::string &v)
-  {
-    defaults[k] = v;
-  }
-
-  void finish(int r) override
-  {
-    daemon_state.clear_updating(key);
-    if (r == 0) {
-      if (key.first == "mds" || key.first == "osd") {
-        json_spirit::mValue json_result;
-        bool read_ok = json_spirit::read(
-            outbl.to_str(), json_result);
-        if (!read_ok) {
-          dout(1) << "mon returned invalid JSON for "
-                  << key.first << "." << key.second << dendl;
-          return;
-        }
-        dout(4) << "mon returned valid metadata JSON for "
+  daemon_state.clear_updating(key);
+  if (r == 0) {
+    if (key.first == "mds" || key.first == "osd") {
+      json_spirit::mValue json_result;
+      bool read_ok = json_spirit::read(
+          outbl.to_str(), json_result);
+      if (!read_ok) {
+        dout(1) << "mon returned invalid JSON for "
                 << key.first << "." << key.second << dendl;
+        return;
+      }
+      dout(4) << "mon returned valid metadata JSON for "
+              << key.first << "." << key.second << dendl;
 
-        json_spirit::mObject daemon_meta = json_result.get_obj();
+      json_spirit::mObject daemon_meta = json_result.get_obj();
 
-        // Apply any defaults
-        for (const auto &i : defaults) {
-          if (daemon_meta.find(i.first) == daemon_meta.end()) {
-            daemon_meta[i.first] = i.second;
-          }
+      // Apply any defaults
+      for (const auto &i : defaults) {
+        if (daemon_meta.find(i.first) == daemon_meta.end()) {
+          daemon_meta[i.first] = i.second;
         }
+      }
 
-        DaemonStatePtr state;
-        if (daemon_state.exists(key)) {
-          state = daemon_state.get(key);
-         Mutex::Locker l(state->lock);
-          if (key.first == "mds") {
-            daemon_meta.erase("name");
-          } else if (key.first == "osd") {
-            daemon_meta.erase("id");
-          }
-          daemon_meta.erase("hostname");
-          state->metadata.clear();
-          for (const auto &i : daemon_meta) {
-            state->metadata[i.first] = i.second.get_str();
-          }
-        } else {
-          state = std::make_shared<DaemonState>(daemon_state.types);
-          state->key = key;
-          state->hostname = daemon_meta.at("hostname").get_str();
-
-          if (key.first == "mds") {
-            daemon_meta.erase("name");
-          } else if (key.first == "osd") {
-            daemon_meta.erase("id");
-          }
-          daemon_meta.erase("hostname");
-
-          for (const auto &i : daemon_meta) {
-            state->metadata[i.first] = i.second.get_str();
-          }
-
-          daemon_state.insert(state);
+      DaemonStatePtr state;
+      if (daemon_state.exists(key)) {
+        state = daemon_state.get(key);
+       Mutex::Locker l(state->lock);
+        if (key.first == "mds") {
+          daemon_meta.erase("name");
+        } else if (key.first == "osd") {
+          daemon_meta.erase("id");
+        }
+        daemon_meta.erase("hostname");
+        state->metadata.clear();
+        for (const auto &i : daemon_meta) {
+          state->metadata[i.first] = i.second.get_str();
         }
       } else {
-        ceph_abort();
+        state = std::make_shared<DaemonState>(daemon_state.types);
+        state->key = key;
+        state->hostname = daemon_meta.at("hostname").get_str();
+
+        if (key.first == "mds") {
+          daemon_meta.erase("name");
+        } else if (key.first == "osd") {
+          daemon_meta.erase("id");
+        }
+        daemon_meta.erase("hostname");
+
+        for (const auto &i : daemon_meta) {
+          state->metadata[i.first] = i.second.get_str();
+        }
+
+        daemon_state.insert(state);
       }
     } else {
-      dout(1) << "mon failed to return metadata for "
-              << key.first << "." << key.second << ": "
-             << cpp_strerror(r) << dendl;
+      ceph_abort();
     }
+  } else {
+    dout(1) << "mon failed to return metadata for "
+            << key.first << "." << key.second << ": "
+           << cpp_strerror(r) << dendl;
   }
-};
-
+}
 
 void Mgr::background_init(Context *completion)
 {
index 68f2b40b4616d62fdfef22f7f7fad093234586c1..b1e6d064946e266f3427b3a2db57c8a9aa6d97fb 100644 (file)
@@ -102,4 +102,33 @@ public:
   std::vector<MonCommand> get_command_set() const;
 };
 
+/**
+ * Context for completion of metadata mon commands: take
+ * the result and stash it in DaemonStateIndex
+ */
+class MetadataUpdate : public Context
+{
+
+private:
+  DaemonStateIndex &daemon_state;
+  DaemonKey key;
+
+  std::map<std::string, std::string> defaults;
+
+public:
+  bufferlist outbl;
+  std::string outs;
+
+  MetadataUpdate(DaemonStateIndex &daemon_state_, const DaemonKey &key_)
+    : daemon_state(daemon_state_), key(key_) {}
+
+  void set_default(const std::string &k, const std::string &v)
+  {
+    defaults[k] = v;
+  }
+
+  void finish(int r) override;
+};
+
+
 #endif