summaryrefslogtreecommitdiffstats
path: root/src/test/objectstore/test_deferred.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/objectstore/test_deferred.cc')
-rw-r--r--src/test/objectstore/test_deferred.cc147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/test/objectstore/test_deferred.cc b/src/test/objectstore/test_deferred.cc
new file mode 100644
index 000000000..f2fd6054f
--- /dev/null
+++ b/src/test/objectstore/test_deferred.cc
@@ -0,0 +1,147 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <memory>
+#include <time.h>
+
+#include "os/ObjectStore.h"
+#include "os/bluestore/BlueStore.h"
+#include "include/Context.h"
+#include "common/ceph_argparse.h"
+#include "global/global_init.h"
+#include "common/ceph_mutex.h"
+#include "common/Cond.h"
+#include "common/errno.h"
+#include "common/options.h" // for the size literals
+#include <semaphore.h>
+
+
+
+class C_do_action : public Context {
+public:
+ std::function<void()> action;
+ C_do_action(std::function<void()> action)
+ : action(action) {}
+
+ void finish(int r) override {
+ action();
+ }
+};
+
+void create_deferred_and_terminate() {
+ std::unique_ptr<ObjectStore> store;
+
+ g_ceph_context->_conf._clear_safe_to_start_threads();
+ g_ceph_context->_conf.set_val_or_die("bluestore_prefer_deferred_size", "4096");
+ g_ceph_context->_conf.set_val_or_die("bluestore_allocator", "bitmap");
+ g_ceph_context->_conf.set_val_or_die("bluestore_block_size", "10240000000");
+ g_ceph_context->_conf.apply_changes(nullptr);
+
+ int64_t poolid;
+ coll_t cid;
+ ghobject_t hoid;
+ ObjectStore::CollectionHandle ch;
+ ceph_assert(::mkdir("bluestore.test_temp_dir", 0777) == 0);
+ store.reset(ObjectStore::create(g_ceph_context,
+ "bluestore",
+ "bluestore.test_temp_dir",
+ "store_test_temp_journal"));
+ ceph_assert(store->mkfs() == 0);
+ ceph_assert(store->mount() == 0);
+
+ poolid = 11;
+ cid = coll_t(spg_t(pg_t(1, poolid), shard_id_t::NO_SHARD));
+ ch = store->create_new_collection(cid);
+ int r;
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ r = store->queue_transaction(ch, std::move(t));
+ ceph_assert(r == 0);
+ }
+
+ {
+ ObjectStore::Transaction t;
+ std::string oid = "zapchajdziura";
+ ghobject_t hoid(hobject_t(oid, "", CEPH_NOSNAP, 1, poolid, ""));
+ bufferlist bl;
+ bl.append(std::string(0xe000, '-'));
+ t.write(cid, hoid, 0, 0xe000, bl);
+ r = store->queue_transaction(ch, std::move(t));
+ ceph_assert(r == 0);
+ }
+
+ size_t object_count = 10;
+
+ // initial fill
+ bufferlist bl_64K;
+ bl_64K.append(std::string(64 * 1024, '-'));
+
+ std::atomic<size_t> prefill_counter{0};
+ sem_t prefill_mutex;
+ sem_init(&prefill_mutex, 0, 0);
+
+ for (size_t o = 0; o < object_count; o++) {
+ ObjectStore::Transaction t;
+ std::string oid = "object-" + std::to_string(o);
+ ghobject_t hoid(hobject_t(oid, "", CEPH_NOSNAP, 1, poolid, ""));
+
+ t.write(cid, hoid, 0, bl_64K.length(), bl_64K);
+ t.register_on_commit(new C_do_action([&] {
+ if (++prefill_counter == object_count) {
+ sem_post(&prefill_mutex);
+ }
+ }));
+
+ r = store->queue_transaction(ch, std::move(t));
+ ceph_assert(r == 0);
+ }
+ sem_wait(&prefill_mutex);
+
+ // small deferred writes over object
+ // and complete overwrite of previous one
+ bufferlist bl_8_bytes;
+ bl_8_bytes.append("abcdefgh");
+ std::atomic<size_t> deferred_counter{0};
+ for (size_t o = 0; o < object_count - 1; o++) {
+ ObjectStore::Transaction t;
+
+ // sprinkle deferred writes
+ std::string oid_d = "object-" + std::to_string(o + 1);
+ ghobject_t hoid_d(hobject_t(oid_d, "", CEPH_NOSNAP, 1, poolid, ""));
+
+ for(int i = 0; i < 16; i++) {
+ t.write(cid, hoid_d, 4096 * i, bl_8_bytes.length(), bl_8_bytes);
+ }
+
+ // overwrite previous object
+ std::string oid_m = "object-" + std::to_string(o);
+ ghobject_t hoid_m(hobject_t(oid_m, "", CEPH_NOSNAP, 1, poolid, ""));
+ t.write(cid, hoid_m, 0, bl_64K.length(), bl_64K);
+
+ t.register_on_commit(new C_do_action([&] {
+ if (++deferred_counter == object_count - 1) {
+ exit(0);
+ }
+ }));
+ r = store->queue_transaction(ch, std::move(t));
+ ceph_assert(r == 0);
+ }
+ sleep(10);
+ ceph_assert(0 && "should not reach here");
+}
+
+int main(int argc, const char **argv) {
+ std::vector<const char*> args;
+ argv_to_vec(argc, argv, args);
+ auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
+ CODE_ENVIRONMENT_UTILITY,
+ CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
+ common_init_finish(g_ceph_context);
+
+ create_deferred_and_terminate();
+ return 0;
+}