diff options
author | Igor Fedotov <igor.fedotov@croit.io> | 2024-01-11 22:13:36 +0100 |
---|---|---|
committer | Igor Fedotov <igor.fedotov@croit.io> | 2024-02-14 11:38:45 +0100 |
commit | d05d0c8ffb868997d8ad8a5e38fc5afb97f855e3 (patch) | |
tree | a7772e7778c6b17db28e49ac0545e3f450f91699 /src/os | |
parent | tool/ceph_objectstore_tool: ignore read errors during pg export (diff) | |
download | ceph-d05d0c8ffb868997d8ad8a5e38fc5afb97f855e3.tar.xz ceph-d05d0c8ffb868997d8ad8a5e38fc5afb97f855e3.zip |
tools/ceph-objectstore-tool: open object store's DB in read-only mode
for operations which permit that.
This provides additional chances to access corrupted object store.
Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
Diffstat (limited to 'src/os')
-rw-r--r-- | src/os/ObjectStore.h | 6 | ||||
-rw-r--r-- | src/os/bluestore/BlueStore.cc | 134 | ||||
-rw-r--r-- | src/os/bluestore/BlueStore.h | 6 |
3 files changed, 142 insertions, 4 deletions
diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h index 302be387fae..83cb540e13c 100644 --- a/src/os/ObjectStore.h +++ b/src/os/ObjectStore.h @@ -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; } diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 29aff834fa4..acf700a95c6 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -8626,6 +8626,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__ << " path " << path << dendl; @@ -13735,7 +13860,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 || - txc->released.size() == 0)) { + txc->released.size() == 0 || + !alloc)) { goto out; } discard_queued = bdev->try_discard(txc->released); @@ -14118,7 +14244,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 @@ -14275,9 +14402,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, diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index f9dba48220c..a661e4a8615 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2948,7 +2948,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(); } |