From dbc82da353494452018288fdcab0750802a7cedf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 11 Sep 2019 16:43:11 -0500 Subject: [PATCH] os/bluestore: test conversion from global statfs Signed-off-by: Sage Weil (cherry picked from commit 923becc88257a70604b313a3ea0419a1024c62d2) --- src/os/bluestore/BlueStore.cc | 11 +++ src/os/bluestore/BlueStore.h | 1 + src/test/objectstore/store_test.cc | 129 +++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 6c1ebdcb5b5b5..18ed527543df6 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -8373,6 +8373,17 @@ void BlueStore::inject_statfs(const string& key, const store_statfs_t& new_statf repairer.apply(db); } +void BlueStore::inject_global_statfs(const store_statfs_t& new_statfs) +{ + KeyValueDB::Transaction t = db->get_transaction(); + volatile_statfs v; + v = new_statfs; + bufferlist bl; + v.encode(bl); + t->set(PREFIX_STAT, BLUESTORE_GLOBAL_STATFS_KEY, bl); + db->submit_transaction_sync(t); +} + void BlueStore::inject_misreference(coll_t cid1, ghobject_t oid1, coll_t cid2, ghobject_t oid2, uint64_t offset) diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index ec82af35c1b51..374034ace2d53 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2691,6 +2691,7 @@ public: void inject_leaked(uint64_t len); void inject_false_free(coll_t cid, ghobject_t oid); void inject_statfs(const string& key, const store_statfs_t& new_statfs); + void inject_global_statfs(const store_statfs_t& new_statfs); void inject_misreference(coll_t cid1, ghobject_t oid1, coll_t cid2, ghobject_t oid2, uint64_t offset); diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index 26b0d33348c49..392ef580cf079 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -7468,6 +7468,135 @@ TEST_P(StoreTestSpecificAUSize, BluestoreRepairTest) { } +TEST_P(StoreTest, BluestoreRepairGlobalStats) +{ + if (string(GetParam()) != "bluestore") + return; + const size_t offs_base = 65536 / 2; + + BlueStore* bstore = dynamic_cast (store.get()); + + // start with global stats + bstore->inject_global_statfs({}); + bstore->umount(); + SetVal(g_conf(), "bluestore_fsck_quick_fix_on_mount", "false"); + bstore->mount(); + + // fill the store with some data + const uint64_t pool = 555; + coll_t cid(spg_t(pg_t(0, pool), shard_id_t::NO_SHARD)); + auto ch = store->create_new_collection(cid); + + ghobject_t hoid = make_object("Object 1", pool); + ghobject_t hoid_dup = make_object("Object 1(dup)", pool); + ghobject_t hoid2 = make_object("Object 2", pool); + ghobject_t hoid_cloned = hoid2; + hoid_cloned.hobj.snap = 1; + ghobject_t hoid3 = make_object("Object 3", pool); + ghobject_t hoid3_cloned = hoid3; + hoid3_cloned.hobj.snap = 1; + bufferlist bl; + bl.append("1234512345"); + int r; + const size_t repeats = 16; + { + auto ch = store->create_new_collection(cid); + cerr << "create collection + write" << std::endl; + ObjectStore::Transaction t; + t.create_collection(cid, 0); + for( auto i = 0ul; i < repeats; ++i ) { + t.write(cid, hoid, i * offs_base, bl.length(), bl); + t.write(cid, hoid_dup, i * offs_base, bl.length(), bl); + } + for( auto i = 0ul; i < repeats; ++i ) { + t.write(cid, hoid2, i * offs_base, bl.length(), bl); + } + t.clone(cid, hoid2, hoid_cloned); + + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + } + + bstore->umount(); + + // enable per-pool stats collection hence causing fsck to fail + cerr << "per-pool statfs" << std::endl; + SetVal(g_conf(), "bluestore_fsck_error_on_no_per_pool_stats", "true"); + g_ceph_context->_conf.apply_changes(nullptr); + + ASSERT_EQ(bstore->fsck(false), 1); + ASSERT_EQ(bstore->repair(false), 0); + ASSERT_EQ(bstore->fsck(false), 0); + + bstore->mount(); +} + +TEST_P(StoreTest, BluestoreRepairGlobalStatsFixOnMount) +{ + if (string(GetParam()) != "bluestore") + return; + const size_t offs_base = 65536 / 2; + + BlueStore* bstore = dynamic_cast (store.get()); + + // start with global stats + bstore->inject_global_statfs({}); + bstore->umount(); + SetVal(g_conf(), "bluestore_fsck_quick_fix_on_mount", "false"); + bstore->mount(); + + // fill the store with some data + const uint64_t pool = 555; + coll_t cid(spg_t(pg_t(0, pool), shard_id_t::NO_SHARD)); + auto ch = store->create_new_collection(cid); + + ghobject_t hoid = make_object("Object 1", pool); + ghobject_t hoid_dup = make_object("Object 1(dup)", pool); + ghobject_t hoid2 = make_object("Object 2", pool); + ghobject_t hoid_cloned = hoid2; + hoid_cloned.hobj.snap = 1; + ghobject_t hoid3 = make_object("Object 3", pool); + ghobject_t hoid3_cloned = hoid3; + hoid3_cloned.hobj.snap = 1; + bufferlist bl; + bl.append("1234512345"); + int r; + const size_t repeats = 16; + { + auto ch = store->create_new_collection(cid); + cerr << "create collection + write" << std::endl; + ObjectStore::Transaction t; + t.create_collection(cid, 0); + for( auto i = 0ul; i < repeats; ++i ) { + t.write(cid, hoid, i * offs_base, bl.length(), bl); + t.write(cid, hoid_dup, i * offs_base, bl.length(), bl); + } + for( auto i = 0ul; i < repeats; ++i ) { + t.write(cid, hoid2, i * offs_base, bl.length(), bl); + } + t.clone(cid, hoid2, hoid_cloned); + + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + } + + bstore->umount(); + + // enable per-pool stats collection hence causing fsck to fail + cerr << "per-pool statfs" << std::endl; + SetVal(g_conf(), "bluestore_fsck_error_on_no_per_pool_stats", "true"); + g_ceph_context->_conf.apply_changes(nullptr); + + ASSERT_EQ(bstore->fsck(false), 1); + + SetVal(g_conf(), "bluestore_fsck_quick_fix_on_mount", "true"); + bstore->mount(); + bstore->umount(); + ASSERT_EQ(bstore->fsck(false), 0); + + bstore->mount(); +} + TEST_P(StoreTest, BluestoreStatistics) { if (string(GetParam()) != "bluestore") return; -- 2.39.5