]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/ceph-objectstore-tool: open object store's DB in read-only mode
authorIgor Fedotov <igor.fedotov@croit.io>
Thu, 11 Jan 2024 21:13:36 +0000 (00:13 +0300)
committerIgor Fedotov <igor.fedotov@croit.io>
Wed, 5 Mar 2025 10:46:11 +0000 (13:46 +0300)
for operations which permit that.
This provides additional chances to access corrupted object store.

Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
(cherry picked from commit d05d0c8ffb868997d8ad8a5e38fc5afb97f855e3)

 Conflicts:
src/os/bluestore/BlueStore.cc
 (trivial)

src/os/ObjectStore.h
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/tools/ceph_objectstore_tool.cc

index fe16facb3f6c08396844cd65d12fb1e0a48508e6..f8e23ace0c5107ca03e02dc5f9fc5d99c245367c 100644 (file)
@@ -269,6 +269,12 @@ public:
   virtual bool test_mount_in_use() = 0;
   virtual int mount() = 0;
   virtual int umount() = 0;
+  virtual int mount_readonly() {
+    return -EOPNOTSUPP;
+  }
+  virtual int umount_readonly() {
+    return -EOPNOTSUPP;
+  }
   virtual int fsck(bool deep) {
     return -EOPNOTSUPP;
   }
index 18913e6833f1b07aaf20818ca5d6b12a69da1ac2..1d44d75eb4c7d560cfd85bff1bf144dc4c1c1095 100644 (file)
@@ -7757,6 +7757,131 @@ bool BlueStore::has_null_manager() const
   return (fm && fm->is_null_manager());
 }
 
+int BlueStore::mount_readonly()
+{
+  int r = _mount_readonly();
+  if (r < 0) {
+    return r;
+  }
+  r = _open_collections();
+  if (r < 0) {
+    return r;
+  }
+  auto shutdown_cache = make_scope_guard([&] {
+    if (!mounted) {
+      _shutdown_cache();
+    }
+  });
+
+  _kv_start();
+  auto stop_kv = make_scope_guard([&] {
+    if (!mounted) {
+      _kv_stop();
+    }
+  });
+
+  r = _deferred_replay();
+  if (r < 0) {
+    return r;
+  }
+  mempool_thread.init();
+  mounted = true;
+  return r;
+}
+
+int BlueStore::_mount_readonly()
+{
+  dout(5) << __func__ << dendl;
+  {
+    string type;
+    int r = read_meta("type", &type);
+    if (r < 0) {
+      derr << __func__ << " failed to load os-type: " << cpp_strerror(r)
+          << dendl;
+      return r;
+     }
+
+     if (type != "bluestore") {
+       derr << __func__ << " expected bluestore, but type is " << type << dendl;
+       return -EIO;
+     }
+   }
+
+  int r = _open_path();
+  if (r < 0)
+    return r;
+  r = _open_fsid(false);
+  if (r < 0)
+    goto out_path;
+
+  r = _read_fsid(&fsid);
+  if (r < 0)
+    goto out_fsid;
+
+  r = _lock_fsid();
+  if (r < 0)
+    goto out_fsid;
+
+  r = _open_bdev(false);
+  if (r < 0)
+    goto out_fsid;
+
+  r = _open_db(false, false, true);
+  if (r < 0)
+    goto out_bdev;
+
+  r = _open_super_meta();
+  if (r < 0) {
+    goto out_db;
+  }
+  return 0;
+
+out_db:
+  _close_db();
+out_bdev:
+  _close_bdev();
+  out_fsid:
+  _close_fsid();
+out_path:
+  _close_path();
+  return r;
+}
+
+int BlueStore::umount_readonly()
+{
+  ceph_assert(_kv_only || mounted);
+  _osr_drain_all();
+
+  mounted = false;
+
+  if (!_kv_only) {
+    mempool_thread.shutdown();
+    dout(20) << __func__ << " stopping kv thread" << dendl;
+    _kv_stop();
+    // skip cache cleanup step on fast shutdown
+    if (likely(!m_fast_shutdown)) {
+      _shutdown_cache();
+    }
+    dout(20) << __func__ << " closing" << dendl;
+  }
+  return _umount_readonly();
+}
+
+int BlueStore::_umount_readonly()
+{
+  dout(5) << __func__ << dendl;
+  if (db) {
+    _close_db();
+  }
+  if (bluefs) {
+    _close_bluefs();
+  }
+  _close_bdev();
+  _close_fsid();
+  _close_path();
+  return 0;
+}
+
 int BlueStore::_mount()
 {
   dout(5) << __func__ << "NCB:: path " << path << dendl;
@@ -13088,7 +13213,8 @@ void BlueStore::_txc_release_alloc(TransContext *txc)
 {
   bool discard_queued = false;
   // it's expected we're called with lazy_release_lock already taken!
-  if (unlikely(cct->_conf->bluestore_debug_no_reuse_blocks)) {
+  if (unlikely(cct->_conf->bluestore_debug_no_reuse_blocks ||
+               !alloc)) {
       goto out;
   }
   discard_queued = bdev->try_discard(txc->released);
@@ -13471,7 +13597,8 @@ void BlueStore::_kv_sync_thread()
       auto sync_start = mono_clock::now();
 #endif
       // submit synct synchronously (block and wait for it to commit)
-      int r = cct->_conf->bluestore_debug_omit_kv_commit ? 0 : db->submit_transaction_sync(synct);
+      int r = db_was_opened_read_only || cct->_conf->bluestore_debug_omit_kv_commit ?
+       0 : db->submit_transaction_sync(synct);
       ceph_assert(r == 0);
 
 #ifdef WITH_BLKIN
@@ -13628,9 +13755,8 @@ void BlueStore::_kv_finalize_thread()
 
       // this is as good a place as any ...
       _reap_collections();
-
       logger->set(l_bluestore_fragmentation,
-         (uint64_t)(alloc->get_fragmentation() * 1000));
+       (uint64_t)(alloc ? alloc->get_fragmentation() * 1000 : 0));
 
       log_latency("kv_final",
        l_bluestore_kv_final_lat,
index ca792a0a855214fc1987ba0a8c5fe0ce705a2044..9896848a8ab2503f911baa7c701960831cd902c9 100644 (file)
@@ -2915,7 +2915,13 @@ public:
 
 private:
   int _mount();
+  int _mount_readonly();
+  int _umount_readonly();
+
 public:
+  int mount_readonly() override;
+  int umount_readonly() override;
+
   int mount() override {
     return _mount();
   }
index 771a052b9c352dcfcda0d6aba7a918ac180bb48b..a5f0794816a9cc5b40cfd15bca644b0eae74c779 100644 (file)
@@ -3847,7 +3847,28 @@ int main(int argc, char **argv)
     return 0;
   }
 
-  int ret = fs->mount();
+  int ret;
+  bool mount_readonly =
+    op == "export" ||
+    op == "list" ||
+    op == "list-pgs" ||
+    op == "meta-list" ||
+    op == "get-osdmap" ||
+    op == "get-superblock" ||
+    op == "get-inc-osdmap" ||
+    objcmd == "get-bytes" ||
+    objcmd == "get-attrs" ||
+    objcmd == "get-omap" ||
+    objcmd == "get-omaphdr" ||
+    objcmd == "list-attrs" ||
+    objcmd == "list-omap" ||
+    objcmd == "dump";
+  if(mount_readonly) {
+    ret = fs->mount_readonly();
+  } else {
+    ret = fs->mount();
+  }
+
   if (ret < 0) {
     if (ret == -EBUSY) {
       cerr << "OSD has the store locked" << std::endl;
@@ -4732,7 +4753,7 @@ out:
     cout <<  ostr.str() << std::endl;
   }
 
-  int r = fs->umount();
+  int r = mount_readonly ? fs->umount_readonly() : fs->umount();
   if (r < 0) {
     cerr << "umount failed: " << cpp_strerror(r) << std::endl;
     // If no previous error, then use umount() error