]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: Add admin socket commands to inspect onode metadata
authorAdam Kupczyk <akupczyk@ibm.com>
Mon, 10 Jun 2024 16:03:24 +0000 (16:03 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Thu, 24 Apr 2025 06:47:18 +0000 (06:47 +0000)
Add admin socket commands:
1) bluestore collections
Lists collections.
2) bluestore list <coll> [start object] [max count]
Lists collection coll starting from object (optional). Default 100 entries. 0 = unlimited.
3) bluestore onode metadata <object>
Prints onode metadata as seen by BlueStore.

It might happen (usually in tests) that 2 BlueStore instances are created at the same time.
Since admin commands are unique, it fails to register.
Use first register to detect whether we can register at all.

Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
src/crimson/os/alienstore/CMakeLists.txt
src/os/CMakeLists.txt
src/os/bluestore/BlueAdmin.cc [new file with mode: 0644]
src/os/bluestore/BlueAdmin.h [new file with mode: 0644]
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/test/objectstore/store_test_fixture.cc

index 5ecde78b5ff726d11ed7db0a22e9c0e77feac3a7..2ba396d93fa8551d514a32615fff1512f6f7394e 100644 (file)
@@ -62,6 +62,7 @@ set(alien_store_srcs
   ${PROJECT_SOURCE_DIR}/src/os/bluestore/Writer.cc
   ${PROJECT_SOURCE_DIR}/src/os/bluestore/Compression.cc
   ${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueStore_debug.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueAdmin.cc
   ${PROJECT_SOURCE_DIR}/src/os/memstore/MemStore.cc)
 
 add_library(crimson-alienstore STATIC
index c98d09b24e2cc38dcbfe33a1b9048404e97f97bd..4a96f4290d61c87254e0c21f384d32b785085069 100644 (file)
@@ -28,6 +28,7 @@ if(WITH_BLUESTORE)
     bluestore/HybridAllocator.cc
     bluestore/Writer.cc
     bluestore/Compression.cc
+    bluestore/BlueAdmin.cc
   )
 endif(WITH_BLUESTORE)
 
diff --git a/src/os/bluestore/BlueAdmin.cc b/src/os/bluestore/BlueAdmin.cc
new file mode 100644 (file)
index 0000000..e765c8d
--- /dev/null
@@ -0,0 +1,150 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "BlueAdmin.h"
+#include "common/pretty_binary.h"
+#include "common/debug.h"
+#include <asm-generic/errno-base.h>
+#include <vector>
+#include <limits>
+
+#define dout_subsys ceph_subsys_bluestore
+#define dout_context store.cct
+
+using ceph::bufferlist;
+using ceph::Formatter;
+using ceph::common::cmd_getval;
+
+BlueStore::SocketHook::SocketHook(BlueStore& store)
+  : store(store)
+{
+  AdminSocket *admin_socket = store.cct->get_admin_socket();
+  if (admin_socket) {
+    int r = admin_socket->register_command(
+      "bluestore collections",
+      this,
+      "list all collections");
+    if (r != 0) {
+      dout(1) << __func__ << " cannot register SocketHook" << dendl;
+      return;
+    }
+    r = admin_socket->register_command(
+      "bluestore list "
+      "name=collection,type=CephString,req=true "
+      "name=start,type=CephString,req=false "
+      "name=max,type=CephInt,req=false",
+      this,
+      "list objects in specific collection");
+    ceph_assert(r == 0);
+    r = admin_socket->register_command(
+      "bluestore onode metadata "
+      "name=object_name,type=CephString,req=true",
+      this,
+      "print object internals");
+    ceph_assert(r == 0);
+  }
+}
+
+BlueStore::SocketHook::~SocketHook()
+{
+  AdminSocket *admin_socket = store.cct->get_admin_socket();
+  if (admin_socket) {
+    admin_socket->unregister_commands(this);
+  }
+}
+
+int BlueStore::SocketHook::call(
+  std::string_view command,
+  const cmdmap_t& cmdmap,
+  const bufferlist& inbl,
+  Formatter *f,
+  std::ostream& ss,
+  bufferlist& out)
+{
+  int r = 0;
+  if (command == "bluestore collections") {
+    std::vector<coll_t> collections;
+    store.list_collections(collections);
+    std::stringstream result;
+    for (const auto& c : collections) {
+      result << c << std::endl;
+    }
+    out.append(result.str());
+    return 0;
+  } else if (command == "bluestore list") {
+    std::string coll;
+    std::string start;
+    int64_t max;
+    cmd_getval(cmdmap, "collection", coll);
+    cmd_getval(cmdmap, "start", start);
+    if (!cmd_getval(cmdmap, "max", max)) {
+      max = 100;
+    }
+    if (max == 0) {
+      max = std::numeric_limits<int>::max();
+    }
+    coll_t c;
+    if (c.parse(coll) == false) {
+      ss << "Cannot parse collection" << std::endl;
+      return -EINVAL;
+    }
+    BlueStore::CollectionRef col = store._get_collection(c);
+    if (!col) {
+      ss << "No such collection" << std::endl;
+      return -ENOENT;
+    }
+    ghobject_t start_object;
+    if (start.length() > 0) {
+      if (start_object.parse(start) == false) {
+        ss << "Cannot parse start object";
+       return -EINVAL;
+      }
+    }
+    std::vector<ghobject_t> list;
+    {
+      std::shared_lock l(col->lock);
+      r = store._collection_list(col.get(), start_object, ghobject_t::get_max(),
+        max, false, &list, nullptr);
+    }
+    if (r != 0) {
+      return 0;
+    }
+    std::stringstream result;
+    for (auto& obj : list) {
+      result << obj << std::endl;
+    }
+    out.append(result.str());
+    return 0;
+  } else if (command == "bluestore onode metadata") {
+    std::string object_name;
+    cmd_getval(cmdmap, "object_name", object_name);
+    ghobject_t object;
+    if (!object.parse(object_name)) {
+      ss << "Cannot parse object" << std::endl;
+      return -EINVAL;
+    }
+    std::shared_lock l(store.coll_lock);
+    for (const auto& cp : store.coll_map) {
+      if (cp.second->contains(object)) {
+        std::shared_lock l(cp.second->lock);
+        OnodeRef o = cp.second->get_onode(object, false);
+        if (!o || !o->exists) {
+          ss << "Object not found" << std::endl;
+          return -ENOENT;
+        }
+        o->extent_map.fault_range(store.db, 0, 0xffffffff);
+        using P = BlueStore::printer;
+        std::stringstream result;
+        result << o->print(P::PTR + P::DISK + P::USE + P::BUF + P::CHK + P::ATTRS) << std::endl;
+        out.append(result.str());
+        return 0;
+      }
+    }
+    r = -ENOENT;
+    ss << "No collection that can hold such object" << std::endl;
+  } else {
+    ss << "Invalid command" << std::endl;
+    r = -ENOSYS;
+  }
+  return r;
+}
diff --git a/src/os/bluestore/BlueAdmin.h b/src/os/bluestore/BlueAdmin.h
new file mode 100644 (file)
index 0000000..9b87077
--- /dev/null
@@ -0,0 +1,30 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_OSD_BLUEADMIN_H
+#define CEPH_OSD_BLUEADMIN_H
+
+
+#include "BlueStore.h"
+#include "common/admin_socket.h"
+
+using std::string;
+using std::to_string;
+
+using ceph::bufferlist;
+using ceph::Formatter;
+
+class BlueStore::SocketHook : public AdminSocketHook {
+  BlueStore& store;
+
+public:
+  SocketHook(BlueStore& store);
+  virtual ~SocketHook();
+  int call(std::string_view command,
+           const cmdmap_t& cmdmap,
+           const bufferlist& inbl,
+           Formatter *f,
+           std::ostream& ss,
+           bufferlist& out) override;
+};
+#endif
index 89c1795d59bcf4ee94ea88d56d1ea30393cc6adf..2d238e8043bede8be1acd3b3d7125168762e1707 100644 (file)
@@ -59,6 +59,7 @@
 #include "kv/KeyValueHistogram.h"
 #include "Writer.h"
 #include "Compression.h"
+#include "BlueAdmin.h"
 
 #if defined(WITH_LTTNG)
 #define TRACEPOINT_DEFINE
@@ -5673,10 +5674,13 @@ BlueStore::BlueStore(CephContext *cct,
   cct->_conf.add_observer(this);
   set_cache_shards(1);
   bluestore_bdev_label_require_all = cct->_conf.get_val<bool>("bluestore_bdev_label_require_all");
+  asok_hook = new SocketHook(*this);
 }
 
 BlueStore::~BlueStore()
 {
+  delete asok_hook;
+  asok_hook = nullptr;
   cct->_conf.remove_observer(this);
   _shutdown_logger();
   ceph_assert(!mounted);
index be4fa407081f232a5b4323d9f72b4c0a457814ed..8c2daedc7e59588d2974dd219fc1af726f060f60 100644 (file)
@@ -58,6 +58,7 @@
 #include "bluestore_common.h"
 #include "BlueFS.h"
 #include "common/EventTrace.h"
+#include "common/admin_socket.h"
 
 #ifdef WITH_BLKIN
 #include "common/zipkin_trace.h"
@@ -2531,6 +2532,10 @@ private:
 
   bool per_pool_stat_collection = true;
 
+  class SocketHook;
+  friend class SocketHook;
+  AdminSocketHook* asok_hook = nullptr;
+
   struct MempoolThread : public Thread {
   public:
     BlueStore *store;
index 3f9b93a3e24cd194274ef40b189debc78f35bc3a..62a199ceaeb9760bfb31002fc235ef213f40e033 100644 (file)
@@ -41,7 +41,7 @@ void StoreTestFixture::SetUp()
     cerr << __func__ << ": unable to create " << data_dir << ": " << cpp_strerror(r) << std::endl;
   }
   ASSERT_EQ(0, r);
-
+  store.reset(nullptr);
   store = ObjectStore::create(g_ceph_context,
                               type,
                               data_dir,