]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/test/objectstore/store_test.cc
update sources to v12.2.5
[ceph.git] / ceph / src / test / objectstore / store_test.cc
index d44373751c7407b7224905ba9d11c27a77a5a253..d2152d4562087144c4b3abc4f4b944ba41a1d12f 100644 (file)
@@ -44,6 +44,7 @@
 
 typedef boost::mt11213b gen_type;
 
+const uint64_t DEF_STORE_TEST_BLOCKDEV_SIZE = 10240000000;
 #define dout_context g_ceph_context
 
 #if GTEST_HAS_PARAM_TEST
@@ -6463,6 +6464,108 @@ TEST_P(StoreTestSpecificAUSize, SmallWriteOnShardedExtents) {
   g_conf->set_val("bluestore_csum_type", "crc32c");
 }
 
+TEST_P(StoreTestSpecificAUSize, ExcessiveFragmentation) {
+  if (string(GetParam()) != "bluestore")
+    return;
+
+  g_conf->set_val("bluestore_block_size",
+    stringify((uint64_t)2048 * 1024 * 1024));
+
+  ASSERT_EQ(g_conf->get_val<uint64_t>("bluefs_alloc_size"),
+           1024 * 1024);
+
+  size_t block_size = 0x10000;
+  StartDeferred(block_size);
+
+  ObjectStore::Sequencer osr("test");
+  int r;
+  coll_t cid;
+  ghobject_t hoid1(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+  ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
+
+  {
+    ObjectStore::Transaction t;
+    t.create_collection(cid, 0);
+    r = apply_transaction(store, &osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+  {
+    // create 2x400MB objects in a way that their pextents are interleaved
+    ObjectStore::Transaction t;
+    bufferlist bl;
+
+    bl.append(std::string(block_size * 4, 'a')); // 256KB
+    uint64_t offs = 0;
+    while(offs < (uint64_t)400 * 1024 * 1024) {
+      t.write(cid, hoid1, offs, bl.length(), bl, 0);
+      t.write(cid, hoid2, offs, bl.length(), bl, 0);
+      r = apply_transaction(store, &osr, std::move(t));
+      ASSERT_EQ(r, 0);
+      offs += bl.length();
+      if( (offs % (100 * 1024 * 1024)) == 0) {
+       std::cout<<"written " << offs << std::endl;
+      }
+    }
+  }
+  std::cout<<"written 800MB"<<std::endl;
+  {
+    // Partially overwrite objects with 100MB each leaving space
+    // fragmented and occuping still unfragmented space at the end
+    // So we'll have enough free space but it'll lack long enough (e.g. 1MB)
+    // contiguous pextents.
+    ObjectStore::Transaction t;
+    bufferlist bl;
+
+    bl.append(std::string(block_size * 4, 'a'));
+    uint64_t offs = 0;
+    while(offs < 112 * 1024 * 1024) {
+      t.write(cid, hoid1, offs, bl.length(), bl, 0);
+      t.write(cid, hoid2, offs, bl.length(), bl, 0);
+      r = apply_transaction(store, &osr, std::move(t));
+      ASSERT_EQ(r, 0);
+      // this will produce high fragmentation if original allocations
+      // were contiguous
+      offs += bl.length();
+      if( (offs % (10 * 1024 * 1024)) == 0) {
+       std::cout<<"written " << offs << std::endl;
+      }
+    }
+  }
+  {
+    // remove one of the object producing much free space
+    // and hence triggering bluefs rebalance.
+    // Which should fail as there is no long enough pextents.
+    ObjectStore::Transaction t;
+    t.remove(cid, hoid2);
+    r = apply_transaction(store, &osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+
+  auto to_sleep = 5 *
+    (int)g_conf->get_val<double>("bluestore_bluefs_balance_interval");
+  std::cout<<"sleeping... " << std::endl;
+  sleep(to_sleep);
+
+  {
+    // touch another object to triggerrebalance
+    ObjectStore::Transaction t;
+    t.touch(cid, hoid1);
+    r = apply_transaction(store, &osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+  {
+    ObjectStore::Transaction t;
+    t.remove(cid, hoid1);
+    t.remove(cid, hoid2);
+    t.remove_collection(cid);
+    cerr << "Cleaning" << std::endl;
+    r = apply_transaction(store, &osr, std::move(t));
+    ASSERT_EQ(r, 0);
+  }
+  g_conf->set_val("bluestore_block_size",
+    stringify(DEF_STORE_TEST_BLOCKDEV_SIZE));
+}
+
 #endif //#if defined(HAVE_LIBAIO)
 
 TEST_P(StoreTest, KVDBHistogramTest) {
@@ -6787,7 +6890,8 @@ int main(int argc, char **argv) {
   g_ceph_context->_conf->set_val("bdev_debug_aio", "true");
 
   // specify device size
-  g_ceph_context->_conf->set_val("bluestore_block_size", "10240000000");
+  g_ceph_context->_conf->set_val("bluestore_block_size",
+    stringify(DEF_STORE_TEST_BLOCKDEV_SIZE));
 
   g_ceph_context->_conf->set_val(
     "enable_experimental_unrecoverable_data_corrupting_features", "*");