Skip to content

Commit

Permalink
tools/ceph-objectstore-tool: open object store's DB in read-only mode
Browse files Browse the repository at this point in the history
for operations which permit that.
This provides additional chances to access corrupted object store.

Signed-off-by: Igor Fedotov <[email protected]>
  • Loading branch information
ifed01 committed Feb 14, 2024
1 parent da13649 commit d05d0c8
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/os/ObjectStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ class ObjectStore {
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;
}
Expand Down
134 changes: 130 additions & 4 deletions src/os/bluestore/BlueStore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions src/os/bluestore/BlueStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -2948,7 +2948,13 @@ class BlueStore : public ObjectStore,

private:
int _mount();
int _mount_readonly();
int _umount_readonly();

public:
int mount_readonly() override;
int umount_readonly() override;

int mount() override {
return _mount();
}
Expand Down
25 changes: 23 additions & 2 deletions src/tools/ceph_objectstore_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3737,7 +3737,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;
Expand Down Expand Up @@ -4625,7 +4646,7 @@ int main(int argc, char **argv)
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
Expand Down

0 comments on commit d05d0c8

Please sign in to comment.