Skip to content

Commit d05d0c8

Browse files
committed
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 <[email protected]>
1 parent da13649 commit d05d0c8

File tree

4 files changed

+165
-6
lines changed

4 files changed

+165
-6
lines changed

src/os/ObjectStore.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,12 @@ class ObjectStore {
269269
virtual bool test_mount_in_use() = 0;
270270
virtual int mount() = 0;
271271
virtual int umount() = 0;
272+
virtual int mount_readonly() {
273+
return -EOPNOTSUPP;
274+
}
275+
virtual int umount_readonly() {
276+
return -EOPNOTSUPP;
277+
}
272278
virtual int fsck(bool deep) {
273279
return -EOPNOTSUPP;
274280
}

src/os/bluestore/BlueStore.cc

Lines changed: 130 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8626,6 +8626,131 @@ bool BlueStore::has_null_manager() const
86268626
return (fm && fm->is_null_manager());
86278627
}
86288628

8629+
int BlueStore::mount_readonly()
8630+
{
8631+
int r = _mount_readonly();
8632+
if (r < 0) {
8633+
return r;
8634+
}
8635+
r = _open_collections();
8636+
if (r < 0) {
8637+
return r;
8638+
}
8639+
auto shutdown_cache = make_scope_guard([&] {
8640+
if (!mounted) {
8641+
_shutdown_cache();
8642+
}
8643+
});
8644+
8645+
_kv_start();
8646+
auto stop_kv = make_scope_guard([&] {
8647+
if (!mounted) {
8648+
_kv_stop();
8649+
}
8650+
});
8651+
8652+
r = _deferred_replay();
8653+
if (r < 0) {
8654+
return r;
8655+
}
8656+
mempool_thread.init();
8657+
mounted = true;
8658+
return r;
8659+
}
8660+
8661+
int BlueStore::_mount_readonly()
8662+
{
8663+
dout(5) << __func__ << dendl;
8664+
{
8665+
string type;
8666+
int r = read_meta("type", &type);
8667+
if (r < 0) {
8668+
derr << __func__ << " failed to load os-type: " << cpp_strerror(r)
8669+
<< dendl;
8670+
return r;
8671+
}
8672+
8673+
if (type != "bluestore") {
8674+
derr << __func__ << " expected bluestore, but type is " << type << dendl;
8675+
return -EIO;
8676+
}
8677+
}
8678+
8679+
int r = _open_path();
8680+
if (r < 0)
8681+
return r;
8682+
r = _open_fsid(false);
8683+
if (r < 0)
8684+
goto out_path;
8685+
8686+
r = _read_fsid(&fsid);
8687+
if (r < 0)
8688+
goto out_fsid;
8689+
8690+
r = _lock_fsid();
8691+
if (r < 0)
8692+
goto out_fsid;
8693+
8694+
r = _open_bdev(false);
8695+
if (r < 0)
8696+
goto out_fsid;
8697+
8698+
r = _open_db(false, false, true);
8699+
if (r < 0)
8700+
goto out_bdev;
8701+
8702+
r = _open_super_meta();
8703+
if (r < 0) {
8704+
goto out_db;
8705+
}
8706+
return 0;
8707+
8708+
out_db:
8709+
_close_db();
8710+
out_bdev:
8711+
_close_bdev();
8712+
out_fsid:
8713+
_close_fsid();
8714+
out_path:
8715+
_close_path();
8716+
return r;
8717+
}
8718+
8719+
int BlueStore::umount_readonly()
8720+
{
8721+
ceph_assert(_kv_only || mounted);
8722+
_osr_drain_all();
8723+
8724+
mounted = false;
8725+
8726+
if (!_kv_only) {
8727+
mempool_thread.shutdown();
8728+
dout(20) << __func__ << " stopping kv thread" << dendl;
8729+
_kv_stop();
8730+
// skip cache cleanup step on fast shutdown
8731+
if (likely(!m_fast_shutdown)) {
8732+
_shutdown_cache();
8733+
}
8734+
dout(20) << __func__ << " closing" << dendl;
8735+
}
8736+
return _umount_readonly();
8737+
}
8738+
8739+
int BlueStore::_umount_readonly()
8740+
{
8741+
dout(5) << __func__ << dendl;
8742+
if (db) {
8743+
_close_db();
8744+
}
8745+
if (bluefs) {
8746+
_close_bluefs();
8747+
}
8748+
_close_bdev();
8749+
_close_fsid();
8750+
_close_path();
8751+
return 0;
8752+
}
8753+
86298754
int BlueStore::_mount()
86308755
{
86318756
dout(5) << __func__ << " path " << path << dendl;
@@ -13735,7 +13860,8 @@ void BlueStore::_txc_release_alloc(TransContext *txc)
1373513860
bool discard_queued = false;
1373613861
// it's expected we're called with lazy_release_lock already taken!
1373713862
if (unlikely(cct->_conf->bluestore_debug_no_reuse_blocks ||
13738-
txc->released.size() == 0)) {
13863+
txc->released.size() == 0 ||
13864+
!alloc)) {
1373913865
goto out;
1374013866
}
1374113867
discard_queued = bdev->try_discard(txc->released);
@@ -14118,7 +14244,8 @@ void BlueStore::_kv_sync_thread()
1411814244
auto sync_start = mono_clock::now();
1411914245
#endif
1412014246
// submit synct synchronously (block and wait for it to commit)
14121-
int r = cct->_conf->bluestore_debug_omit_kv_commit ? 0 : db->submit_transaction_sync(synct);
14247+
int r = db_was_opened_read_only || cct->_conf->bluestore_debug_omit_kv_commit ?
14248+
0 : db->submit_transaction_sync(synct);
1412214249
ceph_assert(r == 0);
1412314250

1412414251
#ifdef WITH_BLKIN
@@ -14275,9 +14402,8 @@ void BlueStore::_kv_finalize_thread()
1427514402

1427614403
// this is as good a place as any ...
1427714404
_reap_collections();
14278-
1427914405
logger->set(l_bluestore_fragmentation,
14280-
(uint64_t)(alloc->get_fragmentation() * 1000));
14406+
(uint64_t)(alloc ? alloc->get_fragmentation() * 1000 : 0));
1428114407

1428214408
log_latency("kv_final",
1428314409
l_bluestore_kv_final_lat,

src/os/bluestore/BlueStore.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,7 +2948,13 @@ class BlueStore : public ObjectStore,
29482948

29492949
private:
29502950
int _mount();
2951+
int _mount_readonly();
2952+
int _umount_readonly();
2953+
29512954
public:
2955+
int mount_readonly() override;
2956+
int umount_readonly() override;
2957+
29522958
int mount() override {
29532959
return _mount();
29542960
}

src/tools/ceph_objectstore_tool.cc

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3737,7 +3737,28 @@ int main(int argc, char **argv)
37373737
return 0;
37383738
}
37393739

3740-
int ret = fs->mount();
3740+
int ret;
3741+
bool mount_readonly =
3742+
op == "export" ||
3743+
op == "list" ||
3744+
op == "list-pgs" ||
3745+
op == "meta-list" ||
3746+
op == "get-osdmap" ||
3747+
op == "get-superblock" ||
3748+
op == "get-inc-osdmap" ||
3749+
objcmd == "get-bytes" ||
3750+
objcmd == "get-attrs" ||
3751+
objcmd == "get-omap" ||
3752+
objcmd == "get-omaphdr" ||
3753+
objcmd == "list-attrs" ||
3754+
objcmd == "list-omap" ||
3755+
objcmd == "dump";
3756+
if(mount_readonly) {
3757+
ret = fs->mount_readonly();
3758+
} else {
3759+
ret = fs->mount();
3760+
}
3761+
37413762
if (ret < 0) {
37423763
if (ret == -EBUSY) {
37433764
cerr << "OSD has the store locked" << std::endl;
@@ -4625,7 +4646,7 @@ int main(int argc, char **argv)
46254646
cout << ostr.str() << std::endl;
46264647
}
46274648

4628-
int r = fs->umount();
4649+
int r = mount_readonly ? fs->umount_readonly() : fs->umount();
46294650
if (r < 0) {
46304651
cerr << "umount failed: " << cpp_strerror(r) << std::endl;
46314652
// If no previous error, then use umount() error

0 commit comments

Comments
 (0)