]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Add dump_watchers to osd admin socket to examine all watchers
authorDavid Zafman <david.zafman@inktank.com>
Fri, 31 May 2013 00:18:24 +0000 (17:18 -0700)
committerDavid Zafman <david.zafman@inktank.com>
Thu, 6 Jun 2013 07:23:19 +0000 (00:23 -0700)
Signed-off-by: David Zafman <david.zafman@inktank.com>
src/osd/OSD.cc
src/osd/PG.h
src/osd/ReplicatedPG.cc
src/osd/ReplicatedPG.h
src/osd/Watch.h
src/osd/osd_types.h

index da41bf6bc11222925323c8557251793c2c64920f..2b52381cdd9632e6bb4351fa5b67aa75d4153834 100644 (file)
@@ -1025,6 +1025,48 @@ bool OSD::asok_command(string command, string args, ostream& ss)
     }
     f.close_section(); //blacklist
     f.flush(ss);
+  } else if (command == "dump_watchers") {
+    list<obj_watch_item_t> watchers;
+    osd_lock.Lock();
+    // scan pg's
+    for (hash_map<pg_t,PG*>::iterator it = pg_map.begin();
+        it != pg_map.end();
+        ++it) {
+
+      list<obj_watch_item_t> pg_watchers;
+      PG *pg = it->second;
+      pg->lock();
+      pg->get_watchers(pg_watchers);
+      pg->unlock();
+      watchers.splice(watchers.end(), pg_watchers);
+    }
+    osd_lock.Unlock();
+
+    JSONFormatter f(true);
+    f.open_array_section("watchers");
+    for (list<obj_watch_item_t>::iterator it = watchers.begin();
+       it != watchers.end(); ++it) {
+
+      f.open_array_section("watch");
+
+      f.dump_string("object", it->obj.oid.name);
+
+      f.open_object_section("entity_name");
+      it->wi.name.dump(&f);
+      f.close_section(); //entity_name_t
+
+      f.dump_int("cookie", it->wi.cookie);
+      f.dump_int("timeout", it->wi.timeout_seconds);
+
+      f.open_object_section("entity_addr_t");
+      it->wi.addr.dump(&f);
+      f.close_section(); //entity_addr_t
+
+      f.close_section(); //watch
+    }
+
+    f.close_section(); //watches
+    f.flush(ss);
   } else {
     assert(0 == "broken asok registration");
   }
@@ -1178,6 +1220,9 @@ int OSD::init()
   r = admin_socket->register_command("dump_blacklist", asok_hook,
                                     "dump_blacklist");
   assert(r == 0);
+  r = admin_socket->register_command("dump_watchers", asok_hook,
+                                    "dump_watchers");
+  assert(r == 0);
 
   test_ops_hook = new TestOpsSocketHook(&(this->service), this->store);
   r = admin_socket->register_command("setomapval", test_ops_hook,
@@ -1377,6 +1422,7 @@ int OSD::shutdown()
   cct->get_admin_socket()->unregister_command("dump_historic_ops");
   cct->get_admin_socket()->unregister_command("dump_op_pq_state");
   cct->get_admin_socket()->unregister_command("dump_blacklist");
+  cct->get_admin_socket()->unregister_command("dump_watchers");
   delete asok_hook;
   asok_hook = NULL;
 
index 845aa8d4604f6b65683b006b8ed3d91b22b9b7c1..107f76bd4d28eb8e543a1a79ad223e304c781988 100644 (file)
@@ -1795,6 +1795,7 @@ public:
   virtual void on_flushed() = 0;
   virtual void on_shutdown() = 0;
   virtual void check_blacklisted_watchers() = 0;
+  virtual void get_watchers(std::list<obj_watch_item_t>&) = 0;
 };
 
 ostream& operator<<(ostream& out, const PG& pg);
index 81e99e6e51c40ad20bb33a63621443df60ec08fb..8228ebd9a25ff8f4a7d2bcf8336e672eda053f65 100644 (file)
@@ -4181,6 +4181,38 @@ void ReplicatedPG::repop_ack(RepGather *repop, int result, int ack_type,
 
 // -------------------------------------------------------
 
+void ReplicatedPG::get_watchers(list<obj_watch_item_t> &pg_watchers)
+{
+  for (map<hobject_t, ObjectContext*>::iterator i = object_contexts.begin();
+       i != object_contexts.end();
+       ++i) {
+    i->second->get();
+    get_obc_watchers(i->second, pg_watchers);
+    put_object_context(i->second);
+  }
+}
+
+void ReplicatedPG::get_obc_watchers(ObjectContext *obc, list<obj_watch_item_t> &pg_watchers)
+{
+  for (map<pair<uint64_t, entity_name_t>, WatchRef>::iterator j =
+        obc->watchers.begin();
+       j != obc->watchers.end();
+       ++j) {
+    obj_watch_item_t owi;
+
+    owi.obj = obc->obs.oi.soid;
+    owi.wi.addr = j->second->get_peer_addr();
+    owi.wi.name = j->second->get_entity();
+    owi.wi.cookie = j->second->get_cookie();
+    owi.wi.timeout_seconds = j->second->get_timeout();
+
+    dout(30) << "watch: Found oid=" << owi.obj << " addr=" << owi.wi.addr
+      << " name=" << owi.wi.name << " cookie=" << owi.wi.cookie << dendl;
+
+    pg_watchers.push_back(owi);
+  }
+}
+
 void ReplicatedPG::check_blacklisted_watchers()
 {
   dout(20) << "ReplicatedPG::check_blacklisted_watchers for pg " << get_pgid() << dendl;
index 7bd28ced5bbf0aec59335ddb077dab2080dcfbe9..d38fdcd51f2d6c08c37bb0ce1d5c4d703aec2416 100644 (file)
@@ -451,6 +451,8 @@ protected:
   void populate_obc_watchers(ObjectContext *obc);
   void check_blacklisted_obc_watchers(ObjectContext *);
   void check_blacklisted_watchers();
+  void get_watchers(list<obj_watch_item_t> &pg_watchers);
+  void get_obc_watchers(ObjectContext *obc, list<obj_watch_item_t> &pg_watchers);
 public:
   void handle_watch_timeout(WatchRef watch);
 protected:
index 44de19ebe0e5437661dea1d4ed505c69b4e900c7..d912e91ed2c8f27fb54c86b0ff3ad2bae7efcc87 100644 (file)
@@ -200,6 +200,7 @@ public:
   uint64_t get_cookie() const { return cookie; }
   entity_name_t get_entity() const { return entity; }
   entity_addr_t get_peer_addr() const { return addr; }
+  uint32_t get_timeout() const { return timeout; }
 
   /// Generates context for use if watch timeout is delayed by scrub or recovery
   Context *get_delayed_cb();
index ab9f034475bc682f29668f64a1f986242243d44a..4c386d4522215519a0fb8ec650673a15be3eb91d 100644 (file)
@@ -2112,6 +2112,11 @@ struct watch_item_t {
 };
 WRITE_CLASS_ENCODER(watch_item_t)
 
+struct obj_watch_item_t {
+  hobject_t obj;
+  watch_item_t wi;
+};
+
 /**
  * obj list watch response format
  *