From 39132b0e460d2d667f02019335dced50d5db641d Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Fri, 5 Nov 2021 12:38:51 +0300 Subject: [PATCH] os/bluestore: do not select absent device in volume selector Fixes: ttps://tracker.ceph.com/issues/53139 Signed-off-by: Igor Fedotov --- src/os/bluestore/BlueFS.cc | 5 +-- src/os/bluestore/BlueStore.cc | 26 +++++++++++- src/os/bluestore/BlueStore.h | 4 ++ src/test/objectstore/store_test.cc | 63 ++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 5 deletions(-) diff --git a/src/os/bluestore/BlueFS.cc b/src/os/bluestore/BlueFS.cc index f34996be3e0..ccc1c154f95 100644 --- a/src/os/bluestore/BlueFS.cc +++ b/src/os/bluestore/BlueFS.cc @@ -3786,10 +3786,9 @@ void* OriginalVolumeSelector::get_hint_by_dir(std::string_view dirname) const { // match up with bluestore. the slow device is always the second // one (when a dedicated block.db device is present and used at // bdev 0). the wal device is always last. - if (boost::algorithm::ends_with(dirname, ".slow")) { + if (boost::algorithm::ends_with(dirname, ".slow") && slow_total) { res = BlueFS::BDEV_SLOW; - } - else if (boost::algorithm::ends_with(dirname, ".wal")) { + } else if (boost::algorithm::ends_with(dirname, ".wal") && wal_total) { res = BlueFS::BDEV_WAL; } } diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index bab1b77e310..221e92ea1c5 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -9425,6 +9425,23 @@ void BlueStore::inject_zombie_spanning_blob(coll_t cid, ghobject_t oid, db->submit_transaction_sync(txn); } +void BlueStore::inject_bluefs_file(std::string_view dir, std::string_view name, size_t new_size) +{ + ceph_assert(bluefs); + + BlueFS::FileWriter* p_handle = nullptr; + auto ret = bluefs->open_for_write(dir, name, &p_handle, false); + ceph_assert(ret == 0); + + std::string s('0', new_size); + bufferlist bl; + bl.append(s); + p_handle->append(bl); + + bluefs->fsync(p_handle); + bluefs->close_writer(p_handle); +} + void BlueStore::collect_metadata(map *pm) { dout(10) << __func__ << dendl; @@ -16767,8 +16784,13 @@ uint8_t RocksDBBlueFSVolumeSelector::select_prefer_bdev(void* h) { void RocksDBBlueFSVolumeSelector::get_paths(const std::string& base, paths& res) const { - res.emplace_back(base, l_totals[LEVEL_DB - LEVEL_FIRST]); - res.emplace_back(base + ".slow", l_totals[LEVEL_SLOW - LEVEL_FIRST]); + auto db_size = l_totals[LEVEL_DB - LEVEL_FIRST]; + res.emplace_back(base, db_size); + auto slow_size = l_totals[LEVEL_SLOW - LEVEL_FIRST]; + if (slow_size == 0) { + slow_size = db_size; + } + res.emplace_back(base + ".slow", slow_size); } void* RocksDBBlueFSVolumeSelector::get_hint_by_dir(std::string_view dirname) const { diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index f575e524a8f..4ca912d3af6 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -3022,6 +3022,10 @@ public: void inject_legacy_omap(coll_t cid, ghobject_t oid); void inject_stray_omap(uint64_t head, const std::string& name); + void inject_bluefs_file(std::string_view dir, + std::string_view name, + size_t new_size); + void compact() override { ceph_assert(db); db->compact(); diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index 6255de952f7..df1d13a9f9f 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -9582,6 +9582,69 @@ TEST_P(StoreTestSpecificAUSize, OmapUpgradeTest) { } } +TEST_P(StoreTestSpecificAUSize, BluefsWriteInSingleDiskEnvTest) { + if (string(GetParam()) != "bluestore") + return; + + g_conf().apply_changes(nullptr); + + StartDeferred(0x1000); + + BlueStore* bstore = dynamic_cast (store.get()); + ceph_assert(bstore); + bstore->inject_bluefs_file("db.slow", "store_test_injection_slow", 1 << 20ul); + bstore->inject_bluefs_file("db.wal", "store_test_injection_wal", 1 << 20ul); + bstore->inject_bluefs_file("db", "store_test_injection_wal", 1 << 20ul); + + AdminSocket* admin_socket = g_ceph_context->get_admin_socket(); + ceph_assert(admin_socket); + + ceph::bufferlist in, out; + ostringstream err; + auto r = admin_socket->execute_command( + { "{\"prefix\": \"bluefs stats\"}" }, + in, err, &out); + if (r != 0) { + cerr << "failure querying: " << cpp_strerror(r) << std::endl; + } else { + std::cout << std::string(out.c_str(), out.length()) << std::endl; + } +} + +TEST_P(StoreTestSpecificAUSize, BluefsWriteInNoWalDiskEnvTest) { + if (string(GetParam()) != "bluestore") + return; + + SetVal(g_conf(), "bluestore_block_db_path", "db"); + SetVal(g_conf(), "bluestore_block_db_size", stringify(1ull << 31).c_str()); + SetVal(g_conf(), "bluestore_block_db_create", "true"); + + g_conf().apply_changes(nullptr); + + StartDeferred(0x1000); + + BlueStore* bstore = dynamic_cast (store.get()); + ceph_assert(bstore); + bstore->inject_bluefs_file("db.slow", "store_test_injection_slow", 1 << 20ul); + bstore->inject_bluefs_file("db.wal", "store_test_injection_wal", 1 << 20ul); + bstore->inject_bluefs_file("db", "store_test_injection_wal", 1 << 20ul); + + AdminSocket* admin_socket = g_ceph_context->get_admin_socket(); + ceph_assert(admin_socket); + + ceph::bufferlist in, out; + ostringstream err; + auto r = admin_socket->execute_command( + { "{\"prefix\": \"bluefs stats\"}" }, + in, err, &out); + if (r != 0) { + cerr << "failure querying: " << cpp_strerror(r) << std::endl; + } + else { + std::cout << std::string(out.c_str(), out.length()) << std::endl; + } +} + #endif // WITH_BLUESTORE int main(int argc, char **argv) { -- 2.39.5