#include "os/ObjectStore.h"
#include "os/filestore/FileStore.h"
-#if defined(HAVE_LIBAIO)
+#if defined(WITH_BLUESTORE)
#include "os/bluestore/BlueStore.h"
+#include "os/bluestore/BlueFS.h"
#endif
#include "include/Context.h"
#include "common/ceph_argparse.h"
+#include "common/admin_socket.h"
#include "global/global_init.h"
-#include "common/Mutex.h"
+#include "common/ceph_mutex.h"
#include "common/Cond.h"
#include "common/errno.h"
#include "include/stringify.h"
#include "include/unordered_map.h"
#include "store_test_fixture.h"
+using namespace std::placeholders;
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
-
static bool bl_eq(bufferlist& expected, bufferlist& actual)
{
if (expected.contents_equal(actual))
<< "expected 0x" << expected.length() << " != actual 0x"
<< actual.length() << std::dec << dendl;
}
- auto len = MIN(expected.length(), actual.length());
+ auto len = std::min(expected.length(), actual.length());
while ( first<len && expected[first] == actual[first])
++first;
unsigned last = len;
template <typename T>
-int apply_transaction(
+int queue_transaction(
T &store,
- ObjectStore::Sequencer *osr,
+ ObjectStore::CollectionHandle ch,
ObjectStore::Transaction &&t) {
if (rand() % 2) {
ObjectStore::Transaction t2;
t2.append(t);
- return store->apply_transaction(osr, std::move(t2));
+ return store->queue_transaction(ch, std::move(t2));
} else {
- return store->apply_transaction(osr, std::move(t));
+ return store->queue_transaction(ch, std::move(t));
}
}
+template <typename T>
+int collection_list(T &store, ObjectStore::CollectionHandle &c,
+ const ghobject_t& start, const ghobject_t& end, int max,
+ vector<ghobject_t> *ls, ghobject_t *pnext,
+ bool disable_legacy = false) {
+ if (disable_legacy || rand() % 2) {
+ return store->collection_list(c, start, end, max, ls, pnext);
+ } else {
+ return store->collection_list_legacy(c, start, end, max, ls, pnext);
+ }
+}
bool sorted(const vector<ghobject_t> &in) {
ghobject_t start;
StoreTest()
: StoreTestFixture(GetParam())
{}
+ void doCompressionTest();
+ void doSyntheticTest(
+ int num_ops,
+ uint64_t max_obj, uint64_t max_wr, uint64_t align);
};
class StoreTestDeferredSetup : public StoreTest {
public:
typedef
std::function<void(
- boost::scoped_ptr<ObjectStore>& store,
uint64_t num_ops,
uint64_t max_obj,
uint64_t max_wr,
uint64_t align)> MatrixTest;
void StartDeferred(size_t min_alloc_size) {
- g_conf->set_val("bluestore_min_alloc_size", stringify(min_alloc_size));
+ SetVal(g_conf(), "bluestore_min_alloc_size", stringify(min_alloc_size).c_str());
DeferredSetup();
}
-
- void TearDown() override {
- g_conf->set_val("bluestore_min_alloc_size", "0");
- StoreTestDeferredSetup::TearDown();
- }
private:
// bluestore matrix testing
return stringify(num_ops);
} else {
char *buf;
- g_conf->get_val(k, &buf, -1);
+ g_conf().get_val(k, &buf, -1);
string v = buf;
free(buf);
return v;
} else if (string(k) == "num_ops") {
num_ops = atoll(v);
} else {
- g_conf->set_val(k, v);
+ SetVal(g_conf(), k, v);
}
}
void do_matrix_choose(const char *matrix[][10],
int i, int pos, int num,
- boost::scoped_ptr<ObjectStore>& store,
MatrixTest fn) {
if (matrix[i][0]) {
int count;
i + 1,
pos * count + j - 1,
num * count,
- store,
fn);
}
} else {
cout << " " << matrix[k][0] << " = " << matrix_get(matrix[k][0])
<< std::endl;
}
- g_ceph_context->_conf->apply_changes(NULL);
- fn(store, num_ops, max_size, max_write, alignment);
+ g_ceph_context->_conf.apply_changes(nullptr);
+ fn(num_ops, max_size, max_write, alignment);
}
}
void do_matrix(const char *matrix[][10],
- boost::scoped_ptr<ObjectStore>& store,
MatrixTest fn) {
- map<string,string> old;
- for (unsigned i=0; matrix[i][0]; ++i) {
- old[matrix[i][0]] = matrix_get(matrix[i][0]);
- }
- cout << "saved config options " << old << std::endl;
if (strcmp(matrix[0][0], "bluestore_min_alloc_size") == 0) {
int count;
TearDown();
}
StartDeferred(strtoll(matrix[0][j], NULL, 10));
- do_matrix_choose(matrix, 1, j - 1, count, store, fn);
+ do_matrix_choose(matrix, 1, j - 1, count, fn);
}
} else {
StartDeferred(0);
- do_matrix_choose(matrix, 0, 0, 1, store, fn);
+ do_matrix_choose(matrix, 0, 0, 1, fn);
}
-
- cout << "restoring config options " << old << std::endl;
- for (auto p : old) {
- cout << " " << p.first << " = " << p.second << std::endl;
- matrix_set(p.first.c_str(), p.second.c_str());
- }
- g_ceph_context->_conf->apply_changes(NULL);
}
};
}
TEST_P(StoreTest, SimpleRemount) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
bufferlist bl;
bl.append("1234512345");
int r;
+ auto ch = store->create_new_collection(cid);
{
cerr << "create collection + write" << std::endl;
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.write(cid, hoid, 0, bl.length(), bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
+ ch.reset();
r = store->umount();
ASSERT_EQ(0, r);
r = store->mount();
ASSERT_EQ(0, r);
+ ch = store->open_collection(cid);
{
ObjectStore::Transaction t;
t.write(cid, hoid2, 0, bl.length(), bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, hoid2);
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
+ ch.reset();
r = store->umount();
ASSERT_EQ(0, r);
r = store->mount();
ASSERT_EQ(0, r);
+ ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, IORemount) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
bufferlist bl;
bl.append("1234512345");
int r;
+ auto ch = store->create_new_collection(cid);
{
cerr << "create collection + objects" << std::endl;
ObjectStore::Transaction t;
ghobject_t hoid(hobject_t(sobject_t("Object " + stringify(n), CEPH_NOSNAP)));
t.write(cid, hoid, 0, bl.length(), bl);
}
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
// overwrites
ObjectStore::Transaction t;
ghobject_t hoid(hobject_t(sobject_t("Object " + stringify(n), CEPH_NOSNAP)));
t.write(cid, hoid, 1, bl.length(), bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
+ ch.reset();
r = store->umount();
ASSERT_EQ(0, r);
r = store->mount();
t.remove(cid, hoid);
}
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->open_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, UnprintableCharsName) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
string name = "funnychars_";
for (unsigned i = 0; i < 256; ++i) {
}
ghobject_t oid(hobject_t(sobject_t(name, CEPH_NOSNAP)));
int r;
+ auto ch = store->create_new_collection(cid);
{
cerr << "create collection + object" << std::endl;
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, oid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
+ ch.reset();
r = store->umount();
ASSERT_EQ(0, r);
r = store->mount();
ObjectStore::Transaction t;
t.remove(cid, oid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->open_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, FiemapEmpty) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
int r = 0;
ghobject_t oid(hobject_t(sobject_t("fiemap_object", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, oid);
t.truncate(cid, oid, 100000);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bufferlist bl;
- store->fiemap(cid, oid, 0, 100000, bl);
+ store->fiemap(ch, oid, 0, 100000, bl);
map<uint64_t,uint64_t> m, e;
- bufferlist::iterator p = bl.begin();
- ::decode(m, p);
+ auto p = bl.cbegin();
+ decode(m, p);
cout << " got " << m << std::endl;
e[0] = 100000;
EXPECT_TRUE(m == e || m.empty());
t.remove(cid, oid);
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, FiemapHoles) {
- ObjectStore::Sequencer osr("test");
const uint64_t MAX_EXTENTS = 4000;
const uint64_t SKIP_STEP = 65536;
coll_t cid;
ghobject_t oid(hobject_t(sobject_t("fiemap_object", CEPH_NOSNAP)));
bufferlist bl;
bl.append("foo");
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, oid);
for (uint64_t i = 0; i < MAX_EXTENTS; i++)
t.write(cid, oid, SKIP_STEP * i, 3, bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
//fiemap test from 0 to SKIP_STEP * (MAX_EXTENTS - 1) + 3
bufferlist bl;
- store->fiemap(cid, oid, 0, SKIP_STEP * (MAX_EXTENTS - 1) + 3, bl);
+ store->fiemap(ch, oid, 0, SKIP_STEP * (MAX_EXTENTS - 1) + 3, bl);
map<uint64_t,uint64_t> m, e;
- bufferlist::iterator p = bl.begin();
- ::decode(m, p);
+ auto p = bl.cbegin();
+ decode(m, p);
cout << " got " << m << std::endl;
ASSERT_TRUE(!m.empty());
ASSERT_GE(m[0], 3u);
- bool extents_exist = true;
- if (m.size() == MAX_EXTENTS) {
- for (uint64_t i = 0; i < MAX_EXTENTS; i++)
- extents_exist = extents_exist && m.count(SKIP_STEP*i);
+ auto last = m.crbegin();
+ if (m.size() == 1) {
+ ASSERT_EQ(0u, last->first);
+ } else if (m.size() == MAX_EXTENTS) {
+ for (uint64_t i = 0; i < MAX_EXTENTS; i++) {
+ ASSERT_TRUE(m.count(SKIP_STEP * i));
+ }
}
- ASSERT_TRUE((m.size() == 1 &&
- m[0] > SKIP_STEP * (MAX_EXTENTS - 1)) ||
- (m.size() == MAX_EXTENTS && extents_exist));
-
+ ASSERT_GT(last->first + last->second, SKIP_STEP * (MAX_EXTENTS - 1));
+ }
+ {
// fiemap test from SKIP_STEP to SKIP_STEP * (MAX_EXTENTS - 2) + 3
- // reset bufferlist and map
- bl.clear();
- m.clear();
- e.clear();
- store->fiemap(cid, oid, SKIP_STEP, SKIP_STEP * (MAX_EXTENTS - 2) + 3, bl);
- p = bl.begin();
- ::decode(m, p);
+ bufferlist bl;
+ store->fiemap(ch, oid, SKIP_STEP, SKIP_STEP * (MAX_EXTENTS - 2) + 3, bl);
+ map<uint64_t,uint64_t> m, e;
+ auto p = bl.cbegin();
+ decode(m, p);
cout << " got " << m << std::endl;
ASSERT_TRUE(!m.empty());
- ASSERT_GE(m[SKIP_STEP], 3u);
- extents_exist = true;
- if (m.size() == (MAX_EXTENTS - 2)) {
- for (uint64_t i = 1; i < MAX_EXTENTS - 1; i++)
- extents_exist = extents_exist && m.count(SKIP_STEP*i);
+ // kstore always returns [0, object_size] regardless of offset and length
+ // FIXME: if fiemap logic in kstore is refined
+ if (string(GetParam()) != "kstore") {
+ ASSERT_GE(m[SKIP_STEP], 3u);
+ auto last = m.crbegin();
+ if (m.size() == 1) {
+ ASSERT_EQ(SKIP_STEP, last->first);
+ } else if (m.size() == MAX_EXTENTS - 2) {
+ for (uint64_t i = 1; i < MAX_EXTENTS - 1; i++) {
+ ASSERT_TRUE(m.count(SKIP_STEP*i));
+ }
+ }
+ ASSERT_GT(last->first + last->second, SKIP_STEP * (MAX_EXTENTS - 1));
}
- ASSERT_TRUE((m.size() == 1 &&
- m[SKIP_STEP] > SKIP_STEP * (MAX_EXTENTS - 2)) ||
- (m.size() == (MAX_EXTENTS - 1) && extents_exist));
}
{
ObjectStore::Transaction t;
t.remove(cid, oid);
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimpleMetaColTest) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
int r = 0;
{
+ auto ch = store->create_new_collection(cid);
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "create collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->open_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
+ auto ch = store->create_new_collection(cid);
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "add collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->open_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimplePGColTest) {
- ObjectStore::Sequencer osr("test");
coll_t cid(spg_t(pg_t(1,2), shard_id_t::NO_SHARD));
int r = 0;
{
ObjectStore::Transaction t;
+ auto ch = store->create_new_collection(cid);
t.create_collection(cid, 4);
cerr << "create collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->open_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.create_collection(cid, 4);
cerr << "add collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->create_new_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ auto ch = store->open_collection(cid);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimpleColPreHashTest) {
- ObjectStore::Sequencer osr("test");
// Firstly we will need to revert the value making sure
// collection hint actually works
int merge_threshold = g_ceph_context->_conf->filestore_merge_threshold;
std::ostringstream oss;
if (merge_threshold > 0) {
oss << "-" << merge_threshold;
- g_ceph_context->_conf->set_val("filestore_merge_threshold", oss.str().c_str());
+ SetVal(g_conf(), "filestore_merge_threshold", oss.str().c_str());
}
uint32_t pg_num = 128;
coll_t cid(spg_t(pg_t(pg_id, 15), shard_id_t::NO_SHARD));
int r;
+ auto ch = store->create_new_collection(cid);
{
// Create a collection along with a hint
ObjectStore::Transaction t;
t.create_collection(cid, 5);
cerr << "create collection" << std::endl;
bufferlist hint;
- ::encode(pg_num, hint);
- ::encode(expected_num_objs, hint);
+ encode(pg_num, hint);
+ encode(expected_num_objs, hint);
t.collection_hint(cid, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
cerr << "collection hint" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "remove collection" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- // Revert the config change so that it does not affect the split/merge tests
- if (merge_threshold > 0) {
- oss.str("");
- oss << merge_threshold;
- g_ceph_context->_conf->set_val("filestore_merge_threshold", oss.str().c_str());
- }
}
TEST_P(StoreTest, SmallBlockWrites) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+ auto ch = store->create_new_collection(cid);
ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist a;
{
ObjectStore::Transaction t;
t.write(cid, hoid, 0, 0x1000, a);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in, exp;
- r = store->read(cid, hoid, 0, 0x4000, in);
+ r = store->read(ch, hoid, 0, 0x4000, in);
ASSERT_EQ(0x1000, r);
exp.append(a);
ASSERT_TRUE(bl_eq(exp, in));
{
ObjectStore::Transaction t;
t.write(cid, hoid, 0x1000, 0x1000, b);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in, exp;
- r = store->read(cid, hoid, 0, 0x4000, in);
+ r = store->read(ch, hoid, 0, 0x4000, in);
ASSERT_EQ(0x2000, r);
exp.append(a);
exp.append(b);
{
ObjectStore::Transaction t;
t.write(cid, hoid, 0x3000, 0x1000, c);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in, exp;
- r = store->read(cid, hoid, 0, 0x4000, in);
+ r = store->read(ch, hoid, 0, 0x4000, in);
ASSERT_EQ(0x4000, r);
exp.append(a);
exp.append(b);
{
ObjectStore::Transaction t;
t.write(cid, hoid, 0x2000, 0x1000, a);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in, exp;
- r = store->read(cid, hoid, 0, 0x4000, in);
+ r = store->read(ch, hoid, 0, 0x4000, in);
ASSERT_EQ(0x4000, r);
exp.append(a);
exp.append(b);
{
ObjectStore::Transaction t;
t.write(cid, hoid, 0, 0x1000, c);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bufferlist in, exp;
- r = store->read(cid, hoid, 0, 0x4000, in);
+ r = store->read(ch, hoid, 0, 0x4000, in);
ASSERT_EQ(0x4000, r);
exp.append(c);
exp.append(b);
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, BufferCacheReadTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
{
- bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
- ASSERT_EQ(-ENOENT, r);
+ auto ch = store->open_collection(cid);
+ ASSERT_FALSE(ch);
}
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- exists = store->exists(cid, hoid);
+ exists = store->exists(ch, hoid);
ASSERT_EQ(true, exists);
}
{
t.write(cid, hoid, 0, 5, bl);
t.write(cid, hoid, 10, 5, bl);
cerr << "TwinWrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, 15, newdata);
+ r = store->read(ch, hoid, 0, 15, newdata);
ASSERT_EQ(r, 15);
{
bufferlist expected;
t.write(cid, hoid, 0, 5, bl);
t.write(cid, hoid, 10, 5, bl);
cerr << "TwinWrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, 15, newdata);
+ r = store->read(ch, hoid, 0, 15, newdata);
ASSERT_EQ(r, 15);
{
bufferlist expected;
t.write(cid, hoid, 20, bl2.length(), bl2);
cerr << "Append" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, 30, newdata);
+ r = store->read(ch, hoid, 0, 30, newdata);
ASSERT_EQ(r, 30);
{
bufferlist expected;
t.write(cid, hoid, 1, bl.length(), bl);
t.write(cid, hoid, 13, bl3.length(), bl3);
cerr << "TripleWrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, 40, newdata);
+ r = store->read(ch, hoid, 0, 40, newdata);
ASSERT_EQ(r, 40);
{
bufferlist expected;
}
}
-void doCompressionTest( boost::scoped_ptr<ObjectStore>& store)
+void StoreTest::doCompressionTest()
{
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
{
- bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
- ASSERT_EQ(-ENOENT, r);
+ auto ch = store->open_collection(cid);
+ ASSERT_FALSE(ch);
}
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- exists = store->exists(cid, hoid);
+ exists = store->exists(ch, hoid);
ASSERT_EQ(true, exists);
}
std::string data;
bl.append(data);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "CompressibleData (4xAU) Write" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, data.size() , newdata);
+ r = store->read(ch, hoid, 0, data.size() , newdata);
ASSERT_EQ(r, (int)data.size());
{
ASSERT_TRUE(bl_eq(expected, newdata));
}
newdata.clear();
- r = store->read(cid, hoid, 0, 711 , newdata);
+ r = store->read(ch, hoid, 0, 711 , newdata);
ASSERT_EQ(r, 711);
{
bufferlist expected;
ASSERT_TRUE(bl_eq(expected, newdata));
}
newdata.clear();
- r = store->read(cid, hoid, 0xf00f, data.size(), newdata);
+ r = store->read(ch, hoid, 0xf00f, data.size(), newdata);
ASSERT_EQ(r, int(data.size() - 0xf00f) );
{
bufferlist expected;
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.stored, (unsigned)data.size());
- ASSERT_LE(statfs.compressed, (unsigned)data.size());
- ASSERT_EQ(statfs.compressed_original, (unsigned)data.size());
- ASSERT_LE(statfs.compressed_allocated, (unsigned)data.size());
+ ASSERT_EQ(statfs.data_stored, (unsigned)data.size());
+ ASSERT_LE(statfs.data_compressed, (unsigned)data.size());
+ ASSERT_EQ(statfs.data_compressed_original, (unsigned)data.size());
+ ASSERT_LE(statfs.data_compressed_allocated, (unsigned)data.size());
}
}
std::string data2;
bl.append(data2);
t.write(cid, hoid, 0x8000, bl.length(), bl);
cerr << "CompressibleData partial overwrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, 0x10000, newdata);
+ r = store->read(ch, hoid, 0, 0x10000, newdata);
ASSERT_EQ(r, (int)0x10000);
{
bufferlist expected;
ASSERT_TRUE(bl_eq(expected, newdata));
}
newdata.clear();
- r = store->read(cid, hoid, 0x9000, 711 , newdata);
+ r = store->read(ch, hoid, 0x9000, 711 , newdata);
ASSERT_EQ(r, 711);
{
bufferlist expected;
ASSERT_TRUE(bl_eq(expected, newdata));
}
newdata.clear();
- r = store->read(cid, hoid, 0x0, 0x40000, newdata);
+ r = store->read(ch, hoid, 0x0, 0x40000, newdata);
ASSERT_EQ(r, int(0x40000) );
{
bufferlist expected;
bl.append(data2);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "CompressibleData partial overwrite, two extents overlapped, single one to be removed" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0, 0x3e000 - 1, newdata);
+ r = store->read(ch, hoid, 0, 0x3e000 - 1, newdata);
ASSERT_EQ(r, (int)0x3e000 - 1);
{
bufferlist expected;
ASSERT_TRUE(bl_eq(expected, newdata));
}
newdata.clear();
- r = store->read(cid, hoid, 0x3e000-1, 0x2001, newdata);
+ r = store->read(ch, hoid, 0x3e000-1, 0x2001, newdata);
ASSERT_EQ(r, 0x2001);
{
bufferlist expected;
ASSERT_TRUE(bl_eq(expected, newdata));
}
newdata.clear();
- r = store->read(cid, hoid, 0x0, 0x40000, newdata);
+ r = store->read(ch, hoid, 0x0, 0x40000, newdata);
ASSERT_EQ(r, int(0x40000) );
{
bufferlist expected;
bl.append(data);
t.write(cid, hoid, 0x3f000-1, bl.length(), bl);
cerr << "Small chunk partial overwrite, two extents overlapped, single one to be removed" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 0x3e000, 0x2000, newdata);
+ r = store->read(ch, hoid, 0x3e000, 0x2000, newdata);
ASSERT_EQ(r, (int)0x2000);
{
bufferlist expected;
ObjectStore::Transaction t;
t.remove(cid, hoid);
cerr << "Cleaning object" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
- auto orig_min_blob_size = g_conf->bluestore_compression_min_blob_size;
+ ch = store->open_collection(cid);
+ auto settingsBookmark = BookmarkSettings();
+ SetVal(g_conf(), "bluestore_compression_min_blob_size", "262144");
+ g_ceph_context->_conf.apply_changes(nullptr);
{
- g_conf->set_val("bluestore_compression_min_blob_size", "262144");
- g_ceph_context->_conf->apply_changes(NULL);
data.resize(0x10000*6);
for(size_t i = 0;i < data.size(); i++)
bl.append(data);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "CompressibleData large blob" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
-
+ ch = store->open_collection(cid);
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_conf->set_val("bluestore_compression_min_blob_size", stringify(orig_min_blob_size));
- g_ceph_context->_conf->apply_changes(NULL);
}
TEST_P(StoreTest, CompressionTest) {
if (string(GetParam()) != "bluestore")
return;
- g_conf->set_val("bluestore_compression_algorithm", "snappy");
- g_conf->set_val("bluestore_compression_mode", "force");
-
- g_ceph_context->_conf->apply_changes(NULL);
-
- doCompressionTest(store);
+ SetVal(g_conf(), "bluestore_compression_algorithm", "snappy");
+ SetVal(g_conf(), "bluestore_compression_mode", "force");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ doCompressionTest();
- g_conf->set_val("bluestore_compression_algorithm", "zlib");
- g_conf->set_val("bluestore_compression_mode", "force");
- g_ceph_context->_conf->apply_changes(NULL);
-
- doCompressionTest(store);
-
- g_conf->set_val("bluestore_compression_algorithm", "snappy");
- g_conf->set_val("bluestore_compression_mode", "none");
- g_ceph_context->_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_compression_algorithm", "zlib");
+ SetVal(g_conf(), "bluestore_compression_mode", "aggressive");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ doCompressionTest();
}
TEST_P(StoreTest, SimpleObjectTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
{
- bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
- ASSERT_EQ(-ENOENT, r);
+ auto ch = store->open_collection(cid);
+ ASSERT_FALSE(ch);
}
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- exists = store->exists(cid, hoid);
+ exists = store->exists(ch, hoid);
ASSERT_EQ(true, exists);
}
{
t.remove(cid, hoid);
t.touch(cid, hoid);
cerr << "Remove then create" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, hoid);
t.write(cid, hoid, 0, 5, bl);
cerr << "Remove then create" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
+ r = store->read(ch, hoid, 0, 5, in);
ASSERT_EQ(5, r);
ASSERT_TRUE(bl_eq(orig, in));
}
exp.append(bl);
t.write(cid, hoid, 5, 5, bl);
cerr << "Append" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in;
- r = store->read(cid, hoid, 0, 10, in);
+ r = store->read(ch, hoid, 0, 10, in);
ASSERT_EQ(10, r);
ASSERT_TRUE(bl_eq(exp, in));
}
exp = bl;
t.write(cid, hoid, 0, 10, bl);
cerr << "Full overwrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in;
- r = store->read(cid, hoid, 0, 10, in);
+ r = store->read(ch, hoid, 0, 10, in);
ASSERT_EQ(10, r);
ASSERT_TRUE(bl_eq(exp, in));
}
bl.append("abcde");
t.write(cid, hoid, 3, 5, bl);
cerr << "Partial overwrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in, exp;
exp.append("abcabcdede");
- r = store->read(cid, hoid, 0, 10, in);
+ r = store->read(ch, hoid, 0, 10, in);
ASSERT_EQ(10, r);
in.hexdump(cout);
ASSERT_TRUE(bl_eq(exp, in));
t.truncate(cid, hoid, 0);
t.write(cid, hoid, 5, 5, bl);
cerr << "Truncate + hole" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append("abcde");
t.write(cid, hoid, 0, 5, bl);
cerr << "Reverse fill-in" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist in, exp;
exp.append("abcdefghij");
- r = store->read(cid, hoid, 0, 10, in);
+ r = store->read(ch, hoid, 0, 10, in);
ASSERT_EQ(10, r);
in.hexdump(cout);
ASSERT_TRUE(bl_eq(exp, in));
bl.append("abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234");
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "larger overwrite" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist in;
- r = store->read(cid, hoid, 0, bl.length(), in);
+ r = store->read(ch, hoid, 0, bl.length(), in);
ASSERT_EQ((int)bl.length(), r);
in.hexdump(cout);
ASSERT_TRUE(bl_eq(bl, in));
//test: offset=len=0 mean read all data
bufferlist in;
- r = store->read(cid, hoid, 0, 0, in);
+ r = store->read(ch, hoid, 0, 0, in);
ASSERT_EQ((int)bl.length(), r);
in.hexdump(cout);
ASSERT_TRUE(bl_eq(bl, in));
t.truncate(cid, hoid, 0);
t.write(cid, hoid, 0x1000-1, bl.length(), bl);
cerr << "Write unaligned csum, stage 1" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
exp1.append(s1);
exp2.append(s2);
exp3.append(s3);
- r = store->read(cid, hoid, 0x1000-1, 1, in);
+ r = store->read(ch, hoid, 0x1000-1, 1, in);
ASSERT_EQ(1, r);
ASSERT_TRUE(bl_eq(exp1, in));
in.clear();
- r = store->read(cid, hoid, 0x1000, 0x1000, in);
+ r = store->read(ch, hoid, 0x1000, 0x1000, in);
ASSERT_EQ(0x1000, r);
ASSERT_TRUE(bl_eq(exp2, in));
bl.append(s3);
t.write(cid, hoid, 1, bl.length(), bl);
cerr << "Write unaligned csum, stage 2" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
in.clear();
- r = store->read(cid, hoid, 1, 2, in);
+ r = store->read(ch, hoid, 1, 2, in);
ASSERT_EQ(2, r);
ASSERT_TRUE(bl_eq(exp3, in));
in.clear();
- r = store->read(cid, hoid, 0x1000-1, 1, in);
+ r = store->read(ch, hoid, 0x1000-1, 1, in);
ASSERT_EQ(1, r);
ASSERT_TRUE(bl_eq(exp1, in));
in.clear();
- r = store->read(cid, hoid, 0x1000, 0x1000, in);
+ r = store->read(ch, hoid, 0x1000, 0x1000, in);
ASSERT_EQ(0x1000, r);
ASSERT_TRUE(bl_eq(exp2, in));
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
-#if defined(HAVE_LIBAIO)
-TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
+#if defined(WITH_BLUESTORE)
+
+TEST_P(StoreTestSpecificAUSize, ReproBug41901Test) {
if(string(GetParam()) != "bluestore")
return;
+ SetVal(g_conf(), "bluestore_debug_enforce_settings", "hdd");
+ g_conf().apply_changes(nullptr);
StartDeferred(65536);
- g_conf->set_val("bluestore_compression_mode", "force");
- // just a big number to disble gc
- g_conf->set_val("bluestore_gc_enable_total_threshold", "100000");
- g_conf->apply_changes(NULL);
int r;
-
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ const PerfCounters* logger = store->get_perf_counters();
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ cerr << "Creating collection " << cid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ bool exists = store->exists(ch, hoid);
+ ASSERT_TRUE(!exists);
+
+ ObjectStore::Transaction t;
+ t.touch(cid, hoid);
+ cerr << "Creating object " << hoid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ exists = store->exists(ch, hoid);
+ ASSERT_EQ(true, exists);
+ }
+ {
+ ObjectStore::Transaction t;
+ bufferlist bl, orig;
+ string s(4096, 'a');
+ bl.append(s);
+ t.write(cid, hoid, 0x11000, bl.length(), bl);
+ cerr << "write1" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ bufferlist bl, orig;
+ string s(4096 * 3, 'a');
+ bl.append(s);
+ t.write(cid, hoid, 0x15000, bl.length(), bl);
+ cerr << "write2" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(logger->get(l_bluestore_write_small), 2u);
+ ASSERT_EQ(logger->get(l_bluestore_write_small_unused), 1u);
+
+ {
+ ObjectStore::Transaction t;
+ bufferlist bl, orig;
+ string s(4096 * 2, 'a');
+ bl.append(s);
+ t.write(cid, hoid, 0xe000, bl.length(), bl);
+ cerr << "write3" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(logger->get(l_bluestore_write_small), 3u);
+ ASSERT_EQ(logger->get(l_bluestore_write_small_unused), 2u);
+
+
+ {
+ ObjectStore::Transaction t;
+ bufferlist bl, orig;
+ string s(4096, 'a');
+ bl.append(s);
+ t.write(cid, hoid, 0xf000, bl.length(), bl);
+ t.write(cid, hoid, 0x10000, bl.length(), bl);
+ cerr << "write3" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(logger->get(l_bluestore_write_small), 5u);
+ ASSERT_EQ(logger->get(l_bluestore_write_small_unused), 2u);
+ {
+ ObjectStore::Transaction t;
+ t.remove(cid, hoid);
+ t.remove_collection(cid);
+ cerr << "Cleaning" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+}
+
+
+TEST_P(StoreTestSpecificAUSize, BluestoreStatFSTest) {
+ if(string(GetParam()) != "bluestore")
+ return;
+ StartDeferred(65536);
+ SetVal(g_conf(), "bluestore_compression_mode", "force");
+ SetVal(g_conf(), "bluestore_max_blob_size", "524288");
+ // just a big number to disble gc
+ SetVal(g_conf(), "bluestore_gc_enable_total_threshold", "100000");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "true");
+ g_conf().apply_changes(nullptr);
+ int r;
+
+ int poolid = 4373;
+ coll_t cid = coll_t(spg_t(pg_t(0, poolid), shard_id_t::NO_SHARD));
+ ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP),
+ string(),
+ 0,
+ poolid,
+ string()));
ghobject_t hoid2 = hoid;
hoid2.hobj.snap = 1;
{
- bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
- ASSERT_EQ(-ENOENT, r);
+ auto ch = store->open_collection(cid);
+ ASSERT_FALSE(ch);
}
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- exists = store->exists(cid, hoid);
+ exists = store->exists(ch, hoid);
ASSERT_EQ(true, exists);
}
{
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ( 0u, statfs.allocated);
- ASSERT_EQ( 0u, statfs.stored);
- ASSERT_EQ(g_conf->bluestore_block_size, statfs.total);
- ASSERT_TRUE(statfs.available > 0u && statfs.available < g_conf->bluestore_block_size);
+ ASSERT_EQ( 0u, statfs.data_stored);
+ ASSERT_EQ(g_conf()->bluestore_block_size, statfs.total);
+ ASSERT_TRUE(statfs.available > 0u && statfs.available < g_conf()->bluestore_block_size);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ( 0u, statfs_pool.allocated);
+ ASSERT_EQ( 0u, statfs_pool.data_stored);
+
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
bl.append("abcde");
t.write(cid, hoid, 0, 5, bl);
cerr << "Append 5 bytes" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(5, statfs.stored);
+ ASSERT_EQ(5, statfs.data_stored);
ASSERT_EQ(0x10000, statfs.allocated);
- ASSERT_EQ(0, statfs.compressed);
- ASSERT_EQ(0, statfs.compressed_original);
- ASSERT_EQ(0, statfs.compressed_allocated);
+ ASSERT_EQ(0, statfs.data_compressed);
+ ASSERT_EQ(0, statfs.data_compressed_original);
+ ASSERT_EQ(0, statfs.data_compressed_allocated);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(5, statfs_pool.data_stored);
+ ASSERT_EQ(0x10000, statfs_pool.allocated);
+ ASSERT_EQ(0, statfs_pool.data_compressed);
+ ASSERT_EQ(0, statfs_pool.data_compressed_original);
+ ASSERT_EQ(0, statfs_pool.data_compressed_allocated);
+
+ // accessing unknown pool
+ r = store->pool_statfs(poolid + 1, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0, statfs_pool.data_stored);
+ ASSERT_EQ(0, statfs_pool.allocated);
+ ASSERT_EQ(0, statfs_pool.data_compressed);
+ ASSERT_EQ(0, statfs_pool.data_compressed_original);
+ ASSERT_EQ(0, statfs_pool.data_compressed_allocated);
+
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
bl.append(s);
t.write(cid, hoid, 0x10000, bl.length(), bl);
cerr << "Append 0x30000 compressible bytes" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(0x30005, statfs.stored);
+ ASSERT_EQ(0x30005, statfs.data_stored);
ASSERT_EQ(0x30000, statfs.allocated);
- ASSERT_LE(statfs.compressed, 0x10000);
- ASSERT_EQ(0x20000, statfs.compressed_original);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_LE(statfs.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000, statfs.data_compressed_original);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0x30005, statfs_pool.data_stored);
+ ASSERT_EQ(0x30000, statfs_pool.allocated);
+ ASSERT_LE(statfs_pool.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000, statfs_pool.data_compressed_original);
+ ASSERT_EQ(statfs_pool.data_compressed_allocated, 0x10000);
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
t.zero(cid, hoid, 1, 3);
t.zero(cid, hoid, 0x20000, 9);
cerr << "Punch hole at 1~3, 0x20000~9" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(0x30005 - 3 - 9, statfs.stored);
+ ASSERT_EQ(0x30005 - 3 - 9, statfs.data_stored);
ASSERT_EQ(0x30000, statfs.allocated);
- ASSERT_LE(statfs.compressed, 0x10000);
- ASSERT_EQ(0x20000 - 9, statfs.compressed_original);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_LE(statfs.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000 - 9, statfs.data_compressed_original);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0x30005 - 3 - 9, statfs_pool.data_stored);
+ ASSERT_EQ(0x30000, statfs_pool.allocated);
+ ASSERT_LE(statfs_pool.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000 - 9, statfs_pool.data_compressed_original);
+ ASSERT_EQ(statfs_pool.data_compressed_allocated, 0x10000);
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
t.write(cid, hoid, 1, bl.length(), bl);
t.write(cid, hoid, 0x10001, bl.length(), bl);
cerr << "Overwrite first and second(compressible) extents" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(0x30001 - 9 + 0x1000, statfs.stored);
+ ASSERT_EQ(0x30001 - 9 + 0x1000, statfs.data_stored);
ASSERT_EQ(0x40000, statfs.allocated);
- ASSERT_LE(statfs.compressed, 0x10000);
- ASSERT_EQ(0x20000 - 9 - 0x1000, statfs.compressed_original);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_LE(statfs.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000 - 9 - 0x1000, statfs.data_compressed_original);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0x30001 - 9 + 0x1000, statfs_pool.data_stored);
+ ASSERT_EQ(0x40000, statfs_pool.allocated);
+ ASSERT_LE(statfs_pool.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000 - 9 - 0x1000, statfs_pool.data_compressed_original);
+ ASSERT_EQ(statfs_pool.data_compressed_allocated, 0x10000);
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
t.write(cid, hoid, 0x20000, bl.length(), bl);
t.write(cid, hoid, 0x30000, bl.length(), bl);
cerr << "Overwrite compressed extent with 3 uncompressible ones" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(0x30000 + 0x1001, statfs.stored);
+ ASSERT_EQ(0x30000 + 0x1001, statfs.data_stored);
ASSERT_EQ(0x40000, statfs.allocated);
- ASSERT_LE(statfs.compressed, 0);
- ASSERT_EQ(0, statfs.compressed_original);
- ASSERT_EQ(0, statfs.compressed_allocated);
+ ASSERT_LE(statfs.data_compressed, 0);
+ ASSERT_EQ(0, statfs.data_compressed_original);
+ ASSERT_EQ(0, statfs.data_compressed_allocated);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0x30000 + 0x1001, statfs_pool.data_stored);
+ ASSERT_EQ(0x40000, statfs_pool.allocated);
+ ASSERT_LE(statfs_pool.data_compressed, 0);
+ ASSERT_EQ(0, statfs_pool.data_compressed_original);
+ ASSERT_EQ(0, statfs_pool.data_compressed_allocated);
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
t.zero(cid, hoid, 0, 0x40000);
cerr << "Zero object" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ(0u, statfs.allocated);
- ASSERT_EQ(0u, statfs.stored);
- ASSERT_EQ(0u, statfs.compressed_original);
- ASSERT_EQ(0u, statfs.compressed);
- ASSERT_EQ(0u, statfs.compressed_allocated);
+ ASSERT_EQ(0u, statfs.data_stored);
+ ASSERT_EQ(0u, statfs.data_compressed_original);
+ ASSERT_EQ(0u, statfs.data_compressed);
+ ASSERT_EQ(0u, statfs.data_compressed_allocated);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0u, statfs_pool.allocated);
+ ASSERT_EQ(0u, statfs_pool.data_stored);
+ ASSERT_EQ(0u, statfs_pool.data_compressed_original);
+ ASSERT_EQ(0u, statfs_pool.data_compressed);
+ ASSERT_EQ(0u, statfs_pool.data_compressed_allocated);
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
ObjectStore::Transaction t;
bl.append(s.substr(0, 0x10000-2));
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "Yet another compressible write" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(0x40000 - 2, statfs.stored);
+ ASSERT_EQ(0x40000 - 2, statfs.data_stored);
ASSERT_EQ(0x30000, statfs.allocated);
- ASSERT_LE(statfs.compressed, 0x10000);
- ASSERT_EQ(0x20000, statfs.compressed_original);
- ASSERT_EQ(0x10000, statfs.compressed_allocated);
+ ASSERT_LE(statfs.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000, statfs.data_compressed_original);
+ ASSERT_EQ(0x10000, statfs.data_compressed_allocated);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(0x40000 - 2, statfs_pool.data_stored);
+ ASSERT_EQ(0x30000, statfs_pool.allocated);
+ ASSERT_LE(statfs_pool.data_compressed, 0x10000);
+ ASSERT_EQ(0x20000, statfs_pool.data_compressed_original);
+ ASSERT_EQ(0x10000, statfs_pool.data_compressed_allocated);
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
}
{
struct store_statfs_t statfs;
r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+
ObjectStore::Transaction t;
t.clone(cid, hoid, hoid2);
cerr << "Clone compressed objecte" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs2;
r = store->statfs(&statfs2);
ASSERT_EQ(r, 0);
- ASSERT_GT(statfs2.stored, statfs.stored);
+ ASSERT_GT(statfs2.data_stored, statfs.data_stored);
ASSERT_EQ(statfs2.allocated, statfs.allocated);
- ASSERT_GT(statfs2.compressed, statfs.compressed);
- ASSERT_GT(statfs2.compressed_original, statfs.compressed_original);
- ASSERT_EQ(statfs2.compressed_allocated, statfs.compressed_allocated);
+ ASSERT_GT(statfs2.data_compressed, statfs.data_compressed);
+ ASSERT_GT(statfs2.data_compressed_original, statfs.data_compressed_original);
+ ASSERT_EQ(statfs2.data_compressed_allocated, statfs.data_compressed_allocated);
+
+ struct store_statfs_t statfs2_pool;
+ r = store->pool_statfs(poolid, &statfs2_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_GT(statfs2_pool.data_stored, statfs_pool.data_stored);
+ ASSERT_EQ(statfs2_pool.allocated, statfs_pool.allocated);
+ ASSERT_GT(statfs2_pool.data_compressed, statfs_pool.data_compressed);
+ ASSERT_GT(statfs2_pool.data_compressed_original,
+ statfs_pool.data_compressed_original);
+ ASSERT_EQ(statfs2_pool.data_compressed_allocated,
+ statfs_pool.data_compressed_allocated);
+ }
+
+ {
+ // verify no
+ auto poolid2 = poolid + 1;
+ coll_t cid2 = coll_t(spg_t(pg_t(20, poolid2), shard_id_t::NO_SHARD));
+ ghobject_t hoid(hobject_t(sobject_t("Object 2", CEPH_NOSNAP),
+ string(),
+ 0,
+ poolid2,
+ string()));
+ auto ch = store->create_new_collection(cid2);
+
+ {
+
+ struct store_statfs_t statfs1_pool;
+ bool per_pool_omap;
+ int r = store->pool_statfs(poolid, &statfs1_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+
+ cerr << "Creating second collection " << cid2 << std::endl;
+ ObjectStore::Transaction t;
+ t.create_collection(cid2, 0);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ t = ObjectStore::Transaction();
+ bufferlist bl;
+ bl.append("abcde");
+ t.write(cid2, hoid, 0, 5, bl);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ struct store_statfs_t statfs2_pool;
+ r = store->pool_statfs(poolid2, &statfs2_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(5, statfs2_pool.data_stored);
+ ASSERT_EQ(0x10000, statfs2_pool.allocated);
+ ASSERT_EQ(0, statfs2_pool.data_compressed);
+ ASSERT_EQ(0, statfs2_pool.data_compressed_original);
+ ASSERT_EQ(0, statfs2_pool.data_compressed_allocated);
+
+ struct store_statfs_t statfs1_pool_again;
+ r = store->pool_statfs(poolid, &statfs1_pool_again, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ // adjust 'available' since it has changed
+ statfs1_pool_again.available = statfs1_pool.available;
+ ASSERT_EQ(statfs1_pool_again, statfs1_pool);
+
+ t = ObjectStore::Transaction();
+ t.remove(cid2, hoid);
+ t.remove_collection(cid2);
+ cerr << "Cleaning" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ }
+
+ {
+ // verify ops on temporary object
+
+ auto poolid3 = poolid + 2;
+ coll_t cid3 = coll_t(spg_t(pg_t(20, poolid3), shard_id_t::NO_SHARD));
+ ghobject_t hoid3(hobject_t(sobject_t("Object 3", CEPH_NOSNAP),
+ string(),
+ 0,
+ poolid3,
+ string()));
+ ghobject_t hoid3_temp;
+ hoid3_temp.hobj = hoid3.hobj.make_temp_hobject("Object 3 temp");
+ auto ch3 = store->create_new_collection(cid3);
+ {
+ struct store_statfs_t statfs1_pool;
+ bool per_pool_omap;
+ int r = store->pool_statfs(poolid, &statfs1_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+
+ cerr << "Creating third collection " << cid3 << std::endl;
+ ObjectStore::Transaction t;
+ t.create_collection(cid3, 0);
+ r = queue_transaction(store, ch3, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ t = ObjectStore::Transaction();
+ bufferlist bl;
+ bl.append("abcde");
+ t.write(cid3, hoid3_temp, 0, 5, bl);
+ r = queue_transaction(store, ch3, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ struct store_statfs_t statfs3_pool;
+ r = store->pool_statfs(poolid3, &statfs3_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(5, statfs3_pool.data_stored);
+ ASSERT_EQ(0x10000, statfs3_pool.allocated);
+ ASSERT_EQ(0, statfs3_pool.data_compressed);
+ ASSERT_EQ(0, statfs3_pool.data_compressed_original);
+ ASSERT_EQ(0, statfs3_pool.data_compressed_allocated);
+
+ struct store_statfs_t statfs1_pool_again;
+ r = store->pool_statfs(poolid, &statfs1_pool_again, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ // adjust 'available' since it has changed
+ statfs1_pool_again.available = statfs1_pool.available;
+ ASSERT_EQ(statfs1_pool_again, statfs1_pool);
+
+ //force fsck
+ ch.reset();
+ ch3.reset();
+ EXPECT_EQ(store->umount(), 0);
+ EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
+ ch3 = store->open_collection(cid3);
+
+ t = ObjectStore::Transaction();
+ t.collection_move_rename(
+ cid3, hoid3_temp,
+ cid3, hoid3);
+ r = queue_transaction(store, ch3, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ struct store_statfs_t statfs3_pool_again;
+ r = store->pool_statfs(poolid3, &statfs3_pool_again, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(statfs3_pool_again, statfs3_pool);
+
+ //force fsck
+ ch.reset();
+ ch3.reset();
+ EXPECT_EQ(store->umount(), 0);
+ EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
+ ch3 = store->open_collection(cid3);
+
+ t = ObjectStore::Transaction();
+ t.remove(cid3, hoid3);
+ t.remove_collection(cid3);
+ cerr << "Cleaning" << std::endl;
+ r = queue_transaction(store, ch3, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
}
{
t.remove(cid, hoid2);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ( 0u, statfs.allocated);
- ASSERT_EQ( 0u, statfs.stored);
- ASSERT_EQ( 0u, statfs.compressed_original);
- ASSERT_EQ( 0u, statfs.compressed);
- ASSERT_EQ( 0u, statfs.compressed_allocated);
- }
- g_conf->set_val("bluestore_gc_enable_total_threshold", "0");
- g_conf->set_val("bluestore_compression_mode", "none");
- g_ceph_context->_conf->apply_changes(NULL);
+ ASSERT_EQ( 0u, statfs.data_stored);
+ ASSERT_EQ( 0u, statfs.data_compressed_original);
+ ASSERT_EQ( 0u, statfs.data_compressed);
+ ASSERT_EQ( 0u, statfs.data_compressed_allocated);
+
+ struct store_statfs_t statfs_pool;
+ bool per_pool_omap;
+ r = store->pool_statfs(poolid, &statfs_pool, &per_pool_omap);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ( 0u, statfs_pool.allocated);
+ ASSERT_EQ( 0u, statfs_pool.data_stored);
+ ASSERT_EQ( 0u, statfs_pool.data_compressed_original);
+ ASSERT_EQ( 0u, statfs_pool.data_compressed);
+ ASSERT_EQ( 0u, statfs_pool.data_compressed_allocated);
+ }
}
TEST_P(StoreTestSpecificAUSize, BluestoreFragmentedBlobTest) {
return;
StartDeferred(0x10000);
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- exists = store->exists(cid, hoid);
+ exists = store->exists(ch, hoid);
ASSERT_EQ(true, exists);
}
{
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(g_conf->bluestore_block_size, statfs.total);
+ ASSERT_EQ(g_conf()->bluestore_block_size, statfs.total);
ASSERT_EQ(0u, statfs.allocated);
- ASSERT_EQ(0u, statfs.stored);
- ASSERT_TRUE(statfs.available > 0u && statfs.available < g_conf->bluestore_block_size);
+ ASSERT_EQ(0u, statfs.data_stored);
+ ASSERT_TRUE(statfs.available > 0u && statfs.available < g_conf()->bluestore_block_size);
}
std::string data;
data.resize(0x10000 * 3);
t.write(cid, hoid, 0, bl.length(), bl);
t.zero(cid, hoid, 0x10000, 0x10000);
cerr << "Append 3*0x10000 bytes and punch a hole 0x10000~10000" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(0x20000, statfs.stored);
+ ASSERT_EQ(0x20000, statfs.data_stored);
ASSERT_EQ(0x20000, statfs.allocated);
- r = store->read(cid, hoid, 0, data.size(), newdata);
+ r = store->read(ch, hoid, 0, data.size(), newdata);
ASSERT_EQ(r, (int)data.size());
{
bufferlist expected;
}
newdata.clear();
- r = store->read(cid, hoid, 1, data.size()-2, newdata);
+ r = store->read(ch, hoid, 1, data.size()-2, newdata);
ASSERT_EQ(r, (int)data.size()-2);
{
bufferlist expected;
newdata.clear();
}
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
{
ObjectStore::Transaction t;
bl.append(data2);
t.write(cid, hoid, 0x20000, bl.length(), bl);
cerr << "Write 3 bytes after the hole" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ(0x20000, statfs.allocated);
- ASSERT_EQ(0x20000, statfs.stored);
+ ASSERT_EQ(0x20000, statfs.data_stored);
- r = store->read(cid, hoid, 0x20000-1, 21, newdata);
+ r = store->read(ch, hoid, 0x20000-1, 21, newdata);
ASSERT_EQ(r, (int)21);
{
bufferlist expected;
newdata.clear();
}
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
{
ObjectStore::Transaction t;
bl.append(data2);
t.write(cid, hoid, 0x10000+1, bl.length(), bl);
cerr << "Write 3 bytes to the hole" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ(0x30000, statfs.allocated);
- ASSERT_EQ(0x20003, statfs.stored);
+ ASSERT_EQ(0x20003, statfs.data_stored);
- r = store->read(cid, hoid, 0x10000-1, 0x10000+22, newdata);
+ r = store->read(ch, hoid, 0x10000-1, 0x10000+22, newdata);
ASSERT_EQ(r, (int)0x10000+22);
{
bufferlist expected;
t.write(cid, hoid, 0, 0x30000, bl);
t.zero(cid, hoid, 0, 0x10000);
t.zero(cid, hoid, 0x20000, 0x10000);
- cerr << "Rewrite an object and create two holes at the begining and the end" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ cerr << "Rewrite an object and create two holes at the beginning and the end" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ(0x10000, statfs.allocated);
- ASSERT_EQ(0x10000, statfs.stored);
+ ASSERT_EQ(0x10000, statfs.data_stored);
- r = store->read(cid, hoid, 0, 0x30000, newdata);
+ r = store->read(ch, hoid, 0, 0x30000, newdata);
ASSERT_EQ(r, (int)0x30000);
{
bufferlist expected;
}
//force fsck
+ ch.reset();
EXPECT_EQ(store->umount(), 0);
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
EXPECT_EQ(store->mount(), 0);
+ ch = store->open_collection(cid);
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct store_statfs_t statfs;
r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
ASSERT_EQ( 0u, statfs.allocated);
- ASSERT_EQ( 0u, statfs.stored);
- ASSERT_EQ( 0u, statfs.compressed_original);
- ASSERT_EQ( 0u, statfs.compressed);
- ASSERT_EQ( 0u, statfs.compressed_allocated);
+ ASSERT_EQ( 0u, statfs.data_stored);
+ ASSERT_EQ( 0u, statfs.data_compressed_original);
+ ASSERT_EQ( 0u, statfs.data_compressed);
+ ASSERT_EQ( 0u, statfs.data_compressed_allocated);
}
}
#endif
TEST_P(StoreTest, ManySmallWrite) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
ghobject_t b(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
for (int i=0; i<100; ++i) {
ObjectStore::Transaction t;
t.write(cid, a, i*4096, 4096, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
for (int i=0; i<100; ++i) {
ObjectStore::Transaction t;
t.write(cid, b, (rand() % 1024)*4096, 4096, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, b);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, MultiSmallWriteSameBlock) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
t.write(cid, a, 9000, 5, bl, 0);
u.write(cid, a, 10, 5, bl, 0);
u.write(cid, a, 7000, 5, bl, 0);
+ t.register_on_commit(&c);
vector<ObjectStore::Transaction> v = {t, u};
- store->queue_transactions(&osr, v, nullptr, &c);
+ store->queue_transactions(ch, v);
}
{
ObjectStore::Transaction t, u;
t.write(cid, a, 6000, 5, bl, 0);
u.write(cid, a, 610, 5, bl, 0);
u.write(cid, a, 11000, 5, bl, 0);
+ t.register_on_commit(&d);
vector<ObjectStore::Transaction> v = {t, u};
- store->queue_transactions(&osr, v, nullptr, &d);
+ store->queue_transactions(ch, v);
}
c.wait();
d.wait();
{
bufferlist bl2;
- r = store->read(cid, a, 0, 16000, bl2);
+ r = store->read(ch, a, 0, 16000, bl2);
ASSERT_GE(r, 0);
}
{
t.remove(cid, a);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SmallSkipFront) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.touch(cid, a);
t.truncate(cid, a, 3000);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(bp);
ObjectStore::Transaction t;
t.write(cid, a, 4096, 4096, bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bufferlist bl;
- ASSERT_EQ(8192, store->read(cid, a, 0, 8192, bl));
+ ASSERT_EQ(8192, store->read(ch, a, 0, 8192, bl));
for (unsigned i=0; i<4096; ++i)
ASSERT_EQ(0, bl[i]);
for (unsigned i=4096; i<8192; ++i)
t.remove(cid, a);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, AppendDeferredVsTailCache) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("fooo", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
- unsigned min_alloc = g_conf->bluestore_min_alloc_size;
- g_conf->set_val("bluestore_inject_deferred_apply_delay", "1.0");
- g_ceph_context->_conf->apply_changes(NULL);
+ unsigned min_alloc = g_conf()->bluestore_min_alloc_size;
unsigned size = min_alloc / 3;
bufferptr bpa(size);
memset(bpa.c_str(), 1, bpa.length());
{
ObjectStore::Transaction t;
t.write(cid, a, 0, bla.length(), bla, 0);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
// force cached tail to clear ...
{
+ ch.reset();
int r = store->umount();
ASSERT_EQ(0, r);
r = store->mount();
ASSERT_EQ(0, r);
+ ch = store->open_collection(cid);
}
bufferptr bpb(size);
{
ObjectStore::Transaction t;
t.write(cid, a, bla.length(), blb.length(), blb, 0);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferptr bpc(size);
{
ObjectStore::Transaction t;
t.write(cid, a, bla.length() + blb.length(), blc.length(), blc, 0);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist final;
bufferlist actual;
{
ASSERT_EQ((int)final.length(),
- store->read(cid, a, 0, final.length(), actual));
+ store->read(ch, a, 0, final.length(), actual));
ASSERT_TRUE(bl_eq(final, actual));
}
{
t.remove(cid, a);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_conf->set_val("bluestore_inject_deferred_apply_delay", "0");
- g_ceph_context->_conf->apply_changes(NULL);
}
TEST_P(StoreTest, AppendZeroTrailingSharedBlock) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("fooo", CEPH_NOSNAP)));
ghobject_t b = a;
b.hobj.snap = 1;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
- unsigned min_alloc = g_conf->bluestore_min_alloc_size;
+ unsigned min_alloc = g_conf()->bluestore_min_alloc_size;
unsigned size = min_alloc / 3;
bufferptr bpa(size);
memset(bpa.c_str(), 1, bpa.length());
bt.append("BADBADBADBAD");
ObjectStore::Transaction t;
t.write(cid, a, 0, bt.length(), bt, 0);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.truncate(cid, a, size);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.clone(cid, a, b);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.write(cid, a, min_alloc * 3, blb.length(), blb, 0);
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist final;
bufferlist actual;
{
ASSERT_EQ((int)final.length(),
- store->read(cid, a, 0, final.length(), actual));
+ store->read(ch, a, 0, final.length(), actual));
final.hexdump(cout);
actual.hexdump(cout);
ASSERT_TRUE(bl_eq(final, actual));
t.remove(cid, b);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = store->apply_transaction(&osr, std::move(t));
+ r = store->queue_transaction(ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SmallSequentialUnaligned) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
for (int i=0; i<1000; ++i) {
ObjectStore::Transaction t;
t.write(cid, a, i*len, len, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, a);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, ManyBigWrite) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
ghobject_t b(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
for (int i=0; i<10; ++i) {
ObjectStore::Transaction t;
t.write(cid, a, i*4*1048586, 4*1048576, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
// aligned
for (int i=0; i<10; ++i) {
ObjectStore::Transaction t;
t.write(cid, b, (rand() % 256)*4*1048576, 4*1048576, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
// unaligned
for (int i=0; i<10; ++i) {
ObjectStore::Transaction t;
t.write(cid, b, (rand() % (256*4096))*1024, 4*1048576, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
// do some zeros
for (int i=0; i<10; ++i) {
ObjectStore::Transaction t;
t.zero(cid, b, (rand() % (256*4096))*1024, 16*1048576);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, b);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, BigWriteBigZero) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
{
ObjectStore::Transaction t;
t.write(cid, a, 0, bl.length(), bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.zero(cid, a, bl.length() / 4, bl.length() / 2);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.write(cid, a, bl.length() / 2, s.length(), s);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove(cid, a);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, MiscFragmentTests) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
{
ObjectStore::Transaction t;
t.write(cid, a, 0, 524288, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.write(cid, a, 1048576, 524288, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bufferlist inbl;
- int r = store->read(cid, a, 524288 + 131072, 1024, inbl);
+ int r = store->read(ch, a, 524288 + 131072, 1024, inbl);
ASSERT_EQ(r, 1024);
ASSERT_EQ(inbl.length(), 1024u);
ASSERT_TRUE(inbl.is_zero());
{
ObjectStore::Transaction t;
t.write(cid, a, 1048576 - 4096, 524288, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, a);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
+TEST_P(StoreTest, ZeroVsObjectSize) {
+ int r;
+ coll_t cid;
+ struct stat stat;
+ ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ cerr << "Creating collection " << cid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ bufferlist a;
+ a.append("stuff");
+ {
+ ObjectStore::Transaction t;
+ t.write(cid, hoid, 0, 5, a);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(0, store->stat(ch, hoid, &stat));
+ ASSERT_EQ(5, stat.st_size);
+ {
+ ObjectStore::Transaction t;
+ t.zero(cid, hoid, 1, 2);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(0, store->stat(ch, hoid, &stat));
+ ASSERT_EQ(5, stat.st_size);
+ {
+ ObjectStore::Transaction t;
+ t.zero(cid, hoid, 3, 200);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(0, store->stat(ch, hoid, &stat));
+ ASSERT_EQ(203, stat.st_size);
+ {
+ ObjectStore::Transaction t;
+ t.zero(cid, hoid, 100000, 200);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ ASSERT_EQ(0, store->stat(ch, hoid, &stat));
+ ASSERT_EQ(100200, stat.st_size);
+}
+
TEST_P(StoreTest, ZeroLengthWrite) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
bufferlist empty;
t.write(cid, hoid, 1048576, 0, empty);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
struct stat stat;
- r = store->stat(cid, hoid, &stat);
+ r = store->stat(ch, hoid, &stat);
+ ASSERT_EQ(0, r);
+ ASSERT_EQ(0, stat.st_size);
+
+ bufferlist newdata;
+ r = store->read(ch, hoid, 0, 1048576, newdata);
+ ASSERT_EQ(0, r);
+}
+
+TEST_P(StoreTest, ZeroLengthZero) {
+ int r;
+ coll_t cid;
+ ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ t.touch(cid, hoid);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(0, r);
+ }
+ {
+ ObjectStore::Transaction t;
+ t.zero(cid, hoid, 1048576, 0);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(0, r);
+ }
+ struct stat stat;
+ r = store->stat(ch, hoid, &stat);
ASSERT_EQ(0, r);
ASSERT_EQ(0, stat.st_size);
bufferlist newdata;
- r = store->read(cid, hoid, 0, 1048576, newdata);
+ r = store->read(ch, hoid, 0, 1048576, newdata);
ASSERT_EQ(0, r);
}
TEST_P(StoreTest, SimpleAttrTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("attr object 1", CEPH_NOSNAP)));
val.append("value");
val.append("value2");
{
- bufferptr bp;
- map<string,bufferptr> aset;
- r = store->getattr(cid, hoid, "nofoo", bp);
- ASSERT_EQ(-ENOENT, r);
- r = store->getattrs(cid, hoid, aset);
- ASSERT_EQ(-ENOENT, r);
+ auto ch = store->open_collection(cid);
+ ASSERT_FALSE(ch);
}
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bool empty;
- int r = store->collection_empty(cid, &empty);
+ int r = store->collection_empty(ch, &empty);
ASSERT_EQ(0, r);
ASSERT_TRUE(empty);
}
{
bufferptr bp;
- r = store->getattr(cid, hoid, "nofoo", bp);
+ r = store->getattr(ch, hoid, "nofoo", bp);
ASSERT_EQ(-ENOENT, r);
}
{
t.touch(cid, hoid);
t.setattr(cid, hoid, "foo", val);
t.setattr(cid, hoid, "bar", val2);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bool empty;
- int r = store->collection_empty(cid, &empty);
+ int r = store->collection_empty(ch, &empty);
ASSERT_EQ(0, r);
ASSERT_TRUE(!empty);
}
{
bufferptr bp;
- r = store->getattr(cid, hoid, "nofoo", bp);
+ r = store->getattr(ch, hoid, "nofoo", bp);
ASSERT_EQ(-ENODATA, r);
- r = store->getattr(cid, hoid, "foo", bp);
+ r = store->getattr(ch, hoid, "foo", bp);
ASSERT_EQ(0, r);
bufferlist bl;
bl.append(bp);
ASSERT_TRUE(bl_eq(val, bl));
map<string,bufferptr> bm;
- r = store->getattrs(cid, hoid, bm);
+ r = store->getattrs(ch, hoid, bm);
ASSERT_EQ(0, r);
}
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimpleListTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid(spg_t(pg_t(0, 1), shard_id_t(1)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
set<ghobject_t> all;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
}
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
vector<ghobject_t> objects;
ghobject_t next, current;
while (!next.is_max()) {
- int r = store->collection_list(cid, current, ghobject_t::get_max(),
- 50,
- &objects, &next);
+ int r = collection_list(store, ch, current, ghobject_t::get_max(), 50,
+ &objects, &next);
ASSERT_EQ(r, 0);
ASSERT_TRUE(sorted(objects));
cout << " got " << objects.size() << " next " << next << std::endl;
t.remove(cid, *p);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, ListEndTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid(spg_t(pg_t(0, 1), shard_id_t(1)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
set<ghobject_t> all;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
}
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
end.hobj.pool = 1;
vector<ghobject_t> objects;
ghobject_t next;
- int r = store->collection_list(cid, ghobject_t(), end, 500,
- &objects, &next);
+ int r = collection_list(store, ch, ghobject_t(), end, 500, &objects, &next);
ASSERT_EQ(r, 0);
for (auto &p : objects) {
ASSERT_NE(p, end);
t.remove(cid, *p);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
}
TEST_P(StoreTest, MultipoolListTest) {
- ObjectStore::Sequencer osr("test");
int r;
int poolid = 4373;
coll_t cid = coll_t(spg_t(pg_t(0, poolid), shard_id_t::NO_SHARD));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
set<ghobject_t> all, saw;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
}
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
vector<ghobject_t> objects;
ghobject_t next, current;
while (!next.is_max()) {
- int r = store->collection_list(cid, current, ghobject_t::get_max(), 50,
- &objects, &next);
+ int r = collection_list(store, ch, current, ghobject_t::get_max(), 50,
+ &objects, &next);
ASSERT_EQ(r, 0);
cout << " got " << objects.size() << " next " << next << std::endl;
for (vector<ghobject_t>::iterator p = objects.begin(); p != objects.end();
t.remove(cid, *p);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimpleCloneTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+
+ SetDeathTestStyle("threadsafe");
+
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP),
t.write(cid, hoid, 0, small.length(), small);
t.write(cid, hoid, 10, small.length(), small);
cerr << "Creating object and set attr " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
t.setattr(cid, hoid, "attr1", large);
t.setattr(cid, hoid, "attr2", small);
cerr << "Clone object and rm attr" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid, 10, 5, newdata);
+ r = store->read(ch, hoid, 10, 5, newdata);
ASSERT_EQ(r, 5);
ASSERT_TRUE(bl_eq(large, newdata));
newdata.clear();
- r = store->read(cid, hoid, 0, 5, newdata);
+ r = store->read(ch, hoid, 0, 5, newdata);
ASSERT_EQ(r, 5);
ASSERT_TRUE(bl_eq(small, newdata));
newdata.clear();
- r = store->read(cid, hoid2, 10, 5, newdata);
+ r = store->read(ch, hoid2, 10, 5, newdata);
ASSERT_EQ(r, 5);
ASSERT_TRUE(bl_eq(small, newdata));
- r = store->getattr(cid, hoid2, "attr2", attr);
+ r = store->getattr(ch, hoid2, "attr2", attr);
ASSERT_EQ(r, 0);
ASSERT_TRUE(bl_eq(small, attr));
attr.clear();
- r = store->getattr(cid, hoid2, "attr3", attr);
+ r = store->getattr(ch, hoid2, "attr3", attr);
ASSERT_EQ(r, 0);
ASSERT_TRUE(bl_eq(xlarge, attr));
attr.clear();
- r = store->getattr(cid, hoid, "attr1", attr);
+ r = store->getattr(ch, hoid, "attr1", attr);
ASSERT_EQ(r, 0);
ASSERT_TRUE(bl_eq(large, attr));
}
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove(cid, hoid2);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
}
{
bufferlist final;
al.append(a);
final.append(a);
t.write(cid, hoid, pl.length(), a.length(), al);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist rl;
ASSERT_EQ((int)final.length(),
- store->read(cid, hoid, 0, final.length(), rl));
+ store->read(ch, hoid, 0, final.length(), rl));
ASSERT_TRUE(bl_eq(rl, final));
}
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove(cid, hoid2);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
}
{
bufferlist final;
al.append(a);
final.append(a);
t.write(cid, hoid, pl.length() + z.length(), a.length(), al);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist rl;
ASSERT_EQ((int)final.length(),
- store->read(cid, hoid, 0, final.length(), rl));
+ store->read(ch, hoid, 0, final.length(), rl));
ASSERT_TRUE(bl_eq(rl, final));
}
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove(cid, hoid2);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
}
{
bufferlist final;
al.append(a);
final.append(a);
t.write(cid, hoid, 17000, a.length(), al);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
bufferlist rl;
ASSERT_EQ((int)final.length(),
- store->read(cid, hoid, 0, final.length(), rl));
+ store->read(ch, hoid, 0, final.length(), rl));
/*cout << "expected:\n";
final.hexdump(cout);
cout << "got:\n";
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove(cid, hoid2);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
}
{
bufferptr p(1048576);
bufferlist al;
al.append(a);
t.write(cid, hoid, a.length(), a.length(), al);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
bufferlist rl;
bufferlist final;
final.substr_of(pl, 0, al.length());
end.substr_of(pl, al.length()*2, pl.length() - al.length()*2);
final.append(end);
ASSERT_EQ((int)final.length(),
- store->read(cid, hoid, 0, final.length(), rl));
+ store->read(ch, hoid, 0, final.length(), rl));
/*cout << "expected:\n";
final.hexdump(cout);
cout << "got:\n";
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove(cid, hoid2);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
}
{
bufferptr p(65536);
bufferlist al;
al.append(a);
t.write(cid, hoid, 32768, a.length(), al);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
bufferlist rl;
bufferlist final;
final.substr_of(pl, 0, 32768);
end.substr_of(pl, final.length(), pl.length() - final.length());
final.append(end);
ASSERT_EQ((int)final.length(),
- store->read(cid, hoid, 0, final.length(), rl));
+ store->read(ch, hoid, 0, final.length(), rl));
/*cout << "expected:\n";
final.hexdump(cout);
cout << "got:\n";
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove(cid, hoid2);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
}
{
bufferptr p(65536);
bufferlist al;
al.append(a);
t.write(cid, hoid, 33768, a.length(), al);
- ASSERT_EQ(0, apply_transaction(store, &osr, std::move(t)));
+ ASSERT_EQ(0, queue_transaction(store, ch, std::move(t)));
bufferlist rl;
bufferlist final;
final.substr_of(pl, 0, 33768);
end.substr_of(pl, final.length(), pl.length() - final.length());
final.append(end);
ASSERT_EQ((int)final.length(),
- store->read(cid, hoid, 0, final.length(), rl));
+ store->read(ch, hoid, 0, final.length(), rl));
/*cout << "expected:\n";
final.hexdump(cout);
cout << "got:\n";
ASSERT_TRUE(bl_eq(rl, final));
}
- //Unfortunately we need a workaround for filestore since EXPECT_DEATH
- // macro has potential issues when using /in multithread environments.
- //It works well for all stores but filestore for now.
- //A fix setting gtest_death_test_style = "threadsafe" doesn't help as well -
- // test app clone asserts on store folder presence.
- //
- if (string(GetParam()) != "filestore") {
+ {
//verify if non-empty collection is properly handled after store reload
+ ch.reset();
r = store->umount();
ASSERT_EQ(r, 0);
r = store->mount();
ASSERT_EQ(r, 0);
+ ch = store->open_collection(cid);
ObjectStore::Transaction t;
t.remove_collection(cid);
cerr << "Invalid rm coll" << std::endl;
PrCtl unset_dumpable;
- EXPECT_DEATH(apply_transaction(store, &osr, std::move(t)), ".*Directory not empty.*");
+ EXPECT_DEATH(queue_transaction(store, ch, std::move(t)), "");
}
{
ObjectStore::Transaction t;
t.touch(cid, hoid3); //new record in db
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- //See comment above for "filestore" check explanation.
- if (string(GetParam()) != "filestore") {
+ {
ObjectStore::Transaction t;
//verify if non-empty collection is properly handled when there are some pending removes and live records in db
cerr << "Invalid rm coll again" << std::endl;
+ ch.reset();
r = store->umount();
ASSERT_EQ(r, 0);
r = store->mount();
ASSERT_EQ(r, 0);
+ ch = store->open_collection(cid);
t.remove(cid, hoid);
t.remove(cid, hoid2);
t.remove_collection(cid);
PrCtl unset_dumpable;
- EXPECT_DEATH(apply_transaction(store, &osr, std::move(t)), ".*Directory not empty.*");
+ EXPECT_DEATH(queue_transaction(store, ch, std::move(t)), "");
}
{
ObjectStore::Transaction t;
t.remove(cid, hoid3);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, OmapSimple) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid(hobject_t(sobject_t("omap_obj", CEPH_NOSNAP),
t.omap_setkeys(cid, hoid, km);
t.omap_setheader(cid, hoid, header);
cerr << "Creating object and set omap " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
// get header, keys
{
bufferlist h;
map<string,bufferlist> r;
- store->omap_get(cid, hoid, &h, &r);
+ store->omap_get(ch, hoid, &h, &r);
ASSERT_TRUE(bl_eq(header, h));
ASSERT_EQ(r.size(), km.size());
cout << "r: " << r << std::endl;
// test iterator with seek_to_first
{
map<string,bufferlist> r;
- ObjectMap::ObjectMapIterator iter = store->get_omap_iterator(cid, hoid);
- for (iter->seek_to_first(); iter->valid(); iter->next(false)) {
+ ObjectMap::ObjectMapIterator iter = store->get_omap_iterator(ch, hoid);
+ for (iter->seek_to_first(); iter->valid(); iter->next()) {
r[iter->key()] = iter->value();
}
cout << "r: " << r << std::endl;
// test iterator with initial lower_bound
{
map<string,bufferlist> r;
- ObjectMap::ObjectMapIterator iter = store->get_omap_iterator(cid, hoid);
- for (iter->lower_bound(string()); iter->valid(); iter->next(false)) {
+ ObjectMap::ObjectMapIterator iter = store->get_omap_iterator(ch, hoid);
+ for (iter->lower_bound(string()); iter->valid(); iter->next()) {
r[iter->key()] = iter->value();
}
cout << "r: " << r << std::endl;
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, OmapCloneTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP),
t.omap_setkeys(cid, hoid, km);
t.omap_setheader(cid, hoid, header);
cerr << "Creating object and set omap " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP),
ObjectStore::Transaction t;
t.clone(cid, hoid, hoid2);
cerr << "Clone object" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
map<string,bufferlist> r;
bufferlist h;
- store->omap_get(cid, hoid2, &h, &r);
+ store->omap_get(ch, hoid2, &h, &r);
ASSERT_TRUE(bl_eq(header, h));
ASSERT_EQ(r.size(), km.size());
}
t.remove(cid, hoid2);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimpleCloneRangeTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
ObjectStore::Transaction t;
t.write(cid, hoid, 10, 5, small);
cerr << "Creating object and write bl " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid2(hobject_t(sobject_t("Object 2", CEPH_NOSNAP)));
ObjectStore::Transaction t;
t.clone_range(cid, hoid, hoid2, 10, 5, 10);
cerr << "Clone range object" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- r = store->read(cid, hoid2, 10, 5, newdata);
+ r = store->read(ch, hoid2, 10, 5, newdata);
ASSERT_EQ(r, 5);
ASSERT_TRUE(bl_eq(small, newdata));
}
t.truncate(cid, hoid, 1024*1024);
t.clone_range(cid, hoid, hoid2, 0, 1024*1024, 0);
cerr << "Clone range object" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
struct stat stat, stat2;
- r = store->stat(cid, hoid, &stat);
- r = store->stat(cid, hoid2, &stat2);
+ r = store->stat(ch, hoid, &stat);
+ r = store->stat(ch, hoid2, &stat2);
ASSERT_EQ(stat.st_size, stat2.st_size);
ASSERT_EQ(1024*1024, stat2.st_size);
}
t.remove(cid, hoid2);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SimpleObjectLongnameTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ghobject_t hoid(hobject_t(sobject_t("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaObjectaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1", CEPH_NOSNAP)));
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
}
TEST_P(StoreTest, LongnameSplitTest) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(0, r);
}
for (unsigned i = 0; i < 320; ++i) {
ghobject_t hoid = generate_long_name(i);
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(0, r);
}
t.collection_move_rename(
cid, test_obj,
cid, test_obj_2);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(0, r);
}
ghobject_t hoid = generate_long_name(i);
t.remove(cid, hoid);
cerr << "Removing object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(0, r);
}
{
t.remove(cid, test_obj_2);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(0, r);
}
}
TEST_P(StoreTest, ManyObjectTest) {
- ObjectStore::Sequencer osr("test");
int NUM_OBJS = 2000;
int r = 0;
coll_t cid;
string base = "";
for (int i = 0; i < 100; ++i) base.append("aaaaa");
set<ghobject_t> created;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
for (int i = 0; i < NUM_OBJS; ++i) {
ghobject_t hoid(hobject_t(sobject_t(string(buf) + base, CEPH_NOSNAP)));
t.touch(cid, hoid);
created.insert(hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
i != created.end();
++i) {
struct stat buf;
- ASSERT_TRUE(!store->stat(cid, *i, &buf));
+ ASSERT_TRUE(!store->stat(ch, *i, &buf));
}
set<ghobject_t> listed, listed2;
vector<ghobject_t> objects;
- r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(), INT_MAX, &objects, 0);
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
ASSERT_EQ(r, 0);
cerr << "objects.size() is " << objects.size() << std::endl;
ghobject_t start, next;
objects.clear();
- r = store->collection_list(
- cid,
+ r = collection_list(
+ store,
+ ch,
ghobject_t::get_max(),
ghobject_t::get_max(),
50,
listed.clear();
ghobject_t start2, next2;
while (1) {
- r = store->collection_list(cid, start, ghobject_t::get_max(),
- 50,
- &objects,
- &next);
+ r = collection_list(store, ch, start, ghobject_t::get_max(), 50, &objects,
+ &next);
ASSERT_TRUE(sorted(objects));
ASSERT_EQ(r, 0);
listed.insert(objects.begin(), objects.end());
++i) {
ObjectStore::Transaction t;
t.remove(cid, *i);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
cerr << "cleaning up" << std::endl;
{
ObjectStore::Transaction t;
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
unsigned in_flight;
map<ghobject_t, Object> contents;
set<ghobject_t> available_objects;
+ set<ghobject_t>::iterator next_available_object;
set<ghobject_t> in_flight_objects;
ObjectGenerator *object_gen;
gen_type *rng;
ObjectStore *store;
- ObjectStore::Sequencer *osr;
+ ObjectStore::CollectionHandle ch;
- Mutex lock;
- Cond cond;
+ ceph::mutex lock = ceph::make_mutex("State lock");
+ ceph::condition_variable cond;
struct EnterExit {
const char *msg;
: state(state), hoid(hoid) {}
void finish(int r) override {
- Mutex::Locker locker(state->lock);
+ std::lock_guard locker{state->lock};
EnterExit ee("onreadable finish");
ASSERT_TRUE(state->in_flight_objects.count(hoid));
ASSERT_EQ(r, 0);
if (state->contents.count(hoid))
state->available_objects.insert(hoid);
--(state->in_flight);
- state->cond.Signal();
+ state->cond.notify_all();
bufferlist r2;
- r = state->store->read(state->cid, hoid, 0, state->contents[hoid].data.length(), r2);
- assert(bl_eq(state->contents[hoid].data, r2));
- state->cond.Signal();
+ r = state->store->read(state->ch, hoid, 0, state->contents[hoid].data.length(), r2);
+ ceph_assert(bl_eq(state->contents[hoid].data, r2));
+ state->cond.notify_all();
}
};
: state(state), oid(oid), noid(noid) {}
void finish(int r) override {
- Mutex::Locker locker(state->lock);
+ std::lock_guard locker{state->lock};
EnterExit ee("stash finish");
ASSERT_TRUE(state->in_flight_objects.count(oid));
ASSERT_EQ(r, 0);
--(state->in_flight);
bufferlist r2;
r = state->store->read(
- state->cid, noid, 0,
+ state->ch, noid, 0,
state->contents[noid].data.length(), r2);
- assert(bl_eq(state->contents[noid].data, r2));
- state->cond.Signal();
+ ceph_assert(bl_eq(state->contents[noid].data, r2));
+ state->cond.notify_all();
}
};
: state(state), oid(oid), noid(noid) {}
void finish(int r) override {
- Mutex::Locker locker(state->lock);
+ std::lock_guard locker{state->lock};
EnterExit ee("clone finish");
ASSERT_TRUE(state->in_flight_objects.count(oid));
ASSERT_EQ(r, 0);
state->available_objects.insert(noid);
--(state->in_flight);
bufferlist r2;
- r = state->store->read(state->cid, noid, 0, state->contents[noid].data.length(), r2);
- assert(bl_eq(state->contents[noid].data, r2));
- state->cond.Signal();
+ r = state->store->read(state->ch, noid, 0, state->contents[noid].data.length(), r2);
+ ceph_assert(bl_eq(state->contents[noid].data, r2));
+ state->cond.notify_all();
}
};
SyntheticWorkloadState(ObjectStore *store,
ObjectGenerator *gen,
gen_type *rng,
- ObjectStore::Sequencer *osr,
coll_t cid,
unsigned max_size,
unsigned max_write,
unsigned alignment)
: cid(cid), write_alignment(alignment), max_object_len(max_size),
- max_write_len(max_write), in_flight(0), object_gen(gen),
- rng(rng), store(store), osr(osr), lock("State lock") {}
+ max_write_len(max_write), in_flight(0),
+ next_available_object(available_objects.end()),
+ object_gen(gen), rng(rng), store(store) {}
int init() {
ObjectStore::Transaction t;
+ ch = store->create_new_collection(cid);
t.create_collection(cid, 0);
- return apply_transaction(store, osr, std::move(t));
+ return queue_transaction(store, ch, std::move(t));
}
void shutdown() {
+ ghobject_t next;
while (1) {
vector<ghobject_t> objects;
- int r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
- 10, &objects, 0);
- assert(r >= 0);
- if (objects.empty())
- break;
+ int r = collection_list(store, ch, next, ghobject_t::get_max(), 10,
+ &objects, &next);
+ ceph_assert(r >= 0);
+ if (objects.size() == 0)
+ break;
ObjectStore::Transaction t;
+ std::map<std::string, ceph::buffer::list> attrset;
for (vector<ghobject_t>::iterator p = objects.begin();
- p != objects.end(); ++p) {
- t.remove(cid, *p);
+ p != objects.end(); ++p) {
+ t.remove(cid, *p);
}
- apply_transaction(store, osr, std::move(t));
+ queue_transaction(store, ch, std::move(t));
}
ObjectStore::Transaction t;
t.remove_collection(cid);
- apply_transaction(store, osr, std::move(t));
+ queue_transaction(store, ch, std::move(t));
}
void statfs(store_statfs_t& stat) {
store->statfs(&stat);
}
- ghobject_t get_uniform_random_object() {
- while (in_flight >= max_in_flight || available_objects.empty())
- cond.Wait(lock);
+ ghobject_t get_uniform_random_object(std::unique_lock<ceph::mutex>& locker) {
+ cond.wait(locker, [this] {
+ return in_flight < max_in_flight && !available_objects.empty();
+ });
boost::uniform_int<> choose(0, available_objects.size() - 1);
int index = choose(*rng);
set<ghobject_t>::iterator i = available_objects.begin();
return ret;
}
- void wait_for_ready() {
- while (in_flight >= max_in_flight)
- cond.Wait(lock);
+ ghobject_t get_next_object(std::unique_lock<ceph::mutex>& locker) {
+ cond.wait(locker, [this] {
+ return in_flight < max_in_flight && !available_objects.empty();
+ });
+
+ if (next_available_object == available_objects.end()) {
+ next_available_object = available_objects.begin();
+ }
+
+ ghobject_t ret = *next_available_object;
+ ++next_available_object;
+ return ret;
+ }
+
+ void wait_for_ready(std::unique_lock<ceph::mutex>& locker) {
+ cond.wait(locker, [this] { return in_flight < max_in_flight; });
}
void wait_for_done() {
- osr->flush();
- Mutex::Locker locker(lock);
- while (in_flight)
- cond.Wait(lock);
+ std::unique_lock locker{lock};
+ cond.wait(locker, [this] { return in_flight == 0; });
}
bool can_create() {
}
int touch() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("touch");
if (!can_create())
return -ENOSPC;
- wait_for_ready();
+ wait_for_ready(locker);
ghobject_t new_obj = object_gen->create_object(rng);
available_objects.erase(new_obj);
ObjectStore::Transaction t;
in_flight_objects.insert(new_obj);
if (!contents.count(new_obj))
contents[new_obj] = Object();
- int status = store->queue_transaction(osr, std::move(t), new C_SyntheticOnReadable(this, new_obj));
+ t.register_on_applied(new C_SyntheticOnReadable(this, new_obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
int stash() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("stash");
if (!can_unlink())
return -ENOENT;
if (!can_create())
return -ENOSPC;
- wait_for_ready();
+ wait_for_ready(locker);
ghobject_t old_obj;
int max = 20;
do {
- old_obj = get_uniform_random_object();
+ old_obj = get_uniform_random_object(locker);
} while (--max && !contents[old_obj].data.length());
available_objects.erase(old_obj);
ghobject_t new_obj = old_obj;
contents[new_obj].attrs = contents[old_obj].attrs;
contents[new_obj].data = contents[old_obj].data;
contents.erase(old_obj);
- int status = store->queue_transaction(
- osr, std::move(t),
- new C_SyntheticOnStash(this, old_obj, new_obj));
+ t.register_on_applied(new C_SyntheticOnStash(this, old_obj, new_obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
int clone() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("clone");
if (!can_unlink())
return -ENOENT;
if (!can_create())
return -ENOSPC;
- wait_for_ready();
+ wait_for_ready(locker);
ghobject_t old_obj;
int max = 20;
do {
- old_obj = get_uniform_random_object();
+ old_obj = get_uniform_random_object(locker);
} while (--max && !contents[old_obj].data.length());
available_objects.erase(old_obj);
ghobject_t new_obj = object_gen->create_object(rng);
contents[new_obj].attrs = contents[old_obj].attrs;
contents[new_obj].data = contents[old_obj].data;
- int status = store->queue_transaction(
- osr, std::move(t),
- new C_SyntheticOnClone(this, old_obj, new_obj));
+ t.register_on_applied(new C_SyntheticOnClone(this, old_obj, new_obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
int clone_range() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("clone_range");
if (!can_unlink())
return -ENOENT;
if (!can_create())
return -ENOSPC;
- wait_for_ready();
+ wait_for_ready(locker);
ghobject_t old_obj;
int max = 20;
do {
- old_obj = get_uniform_random_object();
+ old_obj = get_uniform_random_object(locker);
} while (--max && !contents[old_obj].data.length());
bufferlist &srcdata = contents[old_obj].data;
if (srcdata.length() == 0) {
return 0;
}
available_objects.erase(old_obj);
- ghobject_t new_obj = get_uniform_random_object();
+ ghobject_t new_obj = get_uniform_random_object(locker);
available_objects.erase(new_obj);
boost::uniform_int<> u1(0, max_object_len - max_write_len);
uint64_t dstoff = srcoff; //u1(*rng);
uint64_t len = u2(*rng);
if (write_alignment) {
- srcoff = ROUND_UP_TO(srcoff, write_alignment);
- dstoff = ROUND_UP_TO(dstoff, write_alignment);
- len = ROUND_UP_TO(len, write_alignment);
+ srcoff = round_up_to(srcoff, write_alignment);
+ dstoff = round_up_to(dstoff, write_alignment);
+ len = round_up_to(len, write_alignment);
}
if (srcoff > srcdata.length() - 1) {
}
} else {
bufferlist value;
- assert(dstdata.length() > dstoff);
- dstdata.copy(0, dstoff, value);
+ ceph_assert(dstdata.length() > dstoff);
+ dstdata.cbegin().copy(dstoff, value);
value.append(bl);
if (value.length() < dstdata.length())
- dstdata.copy(value.length(),
- dstdata.length() - value.length(), value);
+ dstdata.cbegin(value.length()).copy(
+ dstdata.length() - value.length(), value);
value.swap(dstdata);
}
- int status = store->queue_transaction(
- osr, std::move(t), new C_SyntheticOnClone(this, old_obj, new_obj));
+ t.register_on_applied(new C_SyntheticOnClone(this, old_obj, new_obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
int write() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("write");
if (!can_unlink())
return -ENOENT;
- wait_for_ready();
+ wait_for_ready(locker);
- ghobject_t new_obj = get_uniform_random_object();
+ ghobject_t new_obj = get_uniform_random_object(locker);
available_objects.erase(new_obj);
ObjectStore::Transaction t;
uint64_t len = u2(*rng);
bufferlist bl;
if (write_alignment) {
- offset = ROUND_UP_TO(offset, write_alignment);
- len = ROUND_UP_TO(len, write_alignment);
+ offset = round_up_to(offset, write_alignment);
+ len = round_up_to(len, write_alignment);
}
filled_byte_array(bl, len);
}
} else {
bufferlist value;
- assert(data.length() > offset);
- data.copy(0, offset, value);
+ ceph_assert(data.length() > offset);
+ data.cbegin().copy(offset, value);
value.append(bl);
if (value.length() < data.length())
- data.copy(value.length(),
- data.length()-value.length(), value);
+ data.cbegin(value.length()).copy(
+ data.length()-value.length(), value);
value.swap(data);
}
t.write(cid, new_obj, offset, len, bl);
++in_flight;
in_flight_objects.insert(new_obj);
- int status = store->queue_transaction(
- osr, std::move(t), new C_SyntheticOnReadable(this, new_obj));
+ t.register_on_applied(new C_SyntheticOnReadable(this, new_obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
int truncate() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("truncate");
if (!can_unlink())
return -ENOENT;
- wait_for_ready();
+ wait_for_ready(locker);
- ghobject_t obj = get_uniform_random_object();
+ ghobject_t obj = get_uniform_random_object(locker);
available_objects.erase(obj);
ObjectStore::Transaction t;
boost::uniform_int<> choose(0, max_object_len);
size_t len = choose(*rng);
if (write_alignment) {
- len = ROUND_UP_TO(len, write_alignment);
+ len = round_up_to(len, write_alignment);
}
t.truncate(cid, obj, len);
data.append_zero(len - data.length());
} else {
bufferlist bl;
- data.copy(0, len, bl);
+ data.cbegin().copy(len, bl);
bl.swap(data);
}
- int status = store->queue_transaction(
- osr, std::move(t), new C_SyntheticOnReadable(this, obj));
+ t.register_on_applied(new C_SyntheticOnReadable(this, obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
int zero() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("zero");
if (!can_unlink())
return -ENOENT;
- wait_for_ready();
+ wait_for_ready(locker);
- ghobject_t new_obj = get_uniform_random_object();
+ ghobject_t new_obj = get_uniform_random_object(locker);
available_objects.erase(new_obj);
ObjectStore::Transaction t;
uint64_t offset = u1(*rng);
uint64_t len = u2(*rng);
if (write_alignment) {
- offset = ROUND_UP_TO(offset, write_alignment);
- len = ROUND_UP_TO(len, write_alignment);
+ offset = round_up_to(offset, write_alignment);
+ len = round_up_to(len, write_alignment);
}
- auto& data = contents[new_obj].data;
- if (data.length() < offset + len) {
- data.append_zero(offset+len-data.length());
+ if (len > 0) {
+ auto& data = contents[new_obj].data;
+ if (data.length() < offset + len) {
+ data.append_zero(offset+len-data.length());
+ }
+ bufferlist n;
+ n.substr_of(data, 0, offset);
+ n.append_zero(len);
+ if (data.length() > offset + len)
+ data.cbegin(offset + len).copy(data.length() - offset - len, n);
+ data.swap(n);
}
- bufferlist n;
- n.substr_of(data, 0, offset);
- n.append_zero(len);
- if (data.length() > offset + len)
- data.copy(offset + len, data.length() - offset - len, n);
- data.swap(n);
t.zero(cid, new_obj, offset, len);
++in_flight;
in_flight_objects.insert(new_obj);
- int status = store->queue_transaction(
- osr, std::move(t), new C_SyntheticOnReadable(this, new_obj));
+ t.register_on_applied(new C_SyntheticOnReadable(this, new_obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
bufferlist expected;
int r;
{
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("read locked");
if (!can_unlink())
return ;
- wait_for_ready();
+ wait_for_ready(locker);
- obj = get_uniform_random_object();
+ obj = get_uniform_random_object(locker);
expected = contents[obj].data;
}
bufferlist bl, result;
<< " size " << expected.length()
<< " offset " << offset
<< " len " << len << std::endl;
- r = store->read(cid, obj, offset, len, result);
+ r = store->read(ch, obj, offset, len, result);
if (offset >= expected.length()) {
ASSERT_EQ(r, 0);
} else {
size_t max_len = expected.length() - offset;
if (len > max_len)
len = max_len;
- assert(len == result.length());
+ ceph_assert(len == result.length());
ASSERT_EQ(len, result.length());
- expected.copy(offset, len, bl);
+ expected.cbegin(offset).copy(len, bl);
ASSERT_EQ(r, (int)len);
ASSERT_TRUE(bl_eq(bl, result));
}
}
int setattrs() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("setattrs");
if (!can_unlink())
return -ENOENT;
- wait_for_ready();
+ wait_for_ready(locker);
- ghobject_t obj = get_uniform_random_object();
+ ghobject_t obj = get_uniform_random_object(locker);
available_objects.erase(obj);
ObjectStore::Transaction t;
t.setattrs(cid, obj, attrs);
++in_flight;
in_flight_objects.insert(obj);
- int status = store->queue_transaction(
- osr, std::move(t), new C_SyntheticOnReadable(this, obj));
+ t.register_on_applied(new C_SyntheticOnReadable(this, obj));
+ int status = store->queue_transaction(ch, std::move(t));
+ return status;
+ }
+
+ int set_fixed_attrs(size_t entries, size_t key_size, size_t val_size) {
+ std::unique_lock locker{ lock };
+ EnterExit ee("setattrs");
+ if (!can_unlink())
+ return -ENOENT;
+ wait_for_ready(locker);
+
+ ghobject_t obj = get_next_object(locker);
+ available_objects.erase(obj);
+ ObjectStore::Transaction t;
+
+ map<string, bufferlist> attrs;
+ set<string> keys;
+
+ while (entries--) {
+ bufferlist name, value;
+ filled_byte_array(value, val_size);
+ filled_byte_array(name, key_size);
+ attrs[name.c_str()] = value;
+ contents[obj].attrs[name.c_str()] = value;
+ }
+ t.setattrs(cid, obj, attrs);
+ ++in_flight;
+ in_flight_objects.insert(obj);
+ t.register_on_applied(new C_SyntheticOnReadable(this, obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
ghobject_t obj;
map<string, bufferlist> expected;
{
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("getattrs locked");
if (!can_unlink())
return ;
- wait_for_ready();
+ wait_for_ready(locker);
int retry = 10;
do {
- obj = get_uniform_random_object();
+ obj = get_uniform_random_object(locker);
if (!--retry)
return ;
} while (contents[obj].attrs.empty());
expected = contents[obj].attrs;
}
map<string, bufferlist> attrs;
- int r = store->getattrs(cid, obj, attrs);
+ int r = store->getattrs(ch, obj, attrs);
ASSERT_TRUE(r == 0);
ASSERT_TRUE(attrs.size() == expected.size());
for (map<string, bufferlist>::iterator it = expected.begin();
int retry;
map<string, bufferlist> expected;
{
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("getattr locked");
if (!can_unlink())
return ;
- wait_for_ready();
+ wait_for_ready(locker);
retry = 10;
do {
- obj = get_uniform_random_object();
+ obj = get_uniform_random_object(locker);
if (!--retry)
return ;
} while (contents[obj].attrs.empty());
}
bufferlist bl;
- r = store->getattr(cid, obj, it->first, bl);
+ r = store->getattr(ch, obj, it->first, bl);
ASSERT_EQ(r, 0);
ASSERT_TRUE(bl_eq(it->second, bl));
}
int rmattr() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("rmattr");
if (!can_unlink())
return -ENOENT;
- wait_for_ready();
+ wait_for_ready(locker);
ghobject_t obj;
int retry = 10;
do {
- obj = get_uniform_random_object();
+ obj = get_uniform_random_object(locker);
if (!--retry)
return 0;
} while (contents[obj].attrs.empty());
contents[obj].attrs.erase(it->first);
++in_flight;
in_flight_objects.insert(obj);
- int status = store->queue_transaction(
- osr, std::move(t), new C_SyntheticOnReadable(this, obj));
+ t.register_on_applied(new C_SyntheticOnReadable(this, obj));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
void fsck(bool deep) {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("fsck");
- while (in_flight)
- cond.Wait(lock);
+ cond.wait(locker, [this] { return in_flight == 0; });
+ ch.reset();
store->umount();
int r = store->fsck(deep);
- assert(r == 0 || r == -EOPNOTSUPP);
+ ceph_assert(r == 0 || r == -EOPNOTSUPP);
store->mount();
+ ch = store->open_collection(cid);
}
void scan() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("scan");
- while (in_flight)
- cond.Wait(lock);
+ cond.wait(locker, [this] { return in_flight == 0; });
vector<ghobject_t> objects;
set<ghobject_t> objects_set, objects_set2;
ghobject_t next, current;
while (1) {
//cerr << "scanning..." << std::endl;
- int r = store->collection_list(cid, current, ghobject_t::get_max(), 100,
- &objects, &next);
+ int r = collection_list(store, ch, current, ghobject_t::get_max(), 100,
+ &objects, &next);
ASSERT_EQ(r, 0);
ASSERT_TRUE(sorted(objects));
objects_set.insert(objects.begin(), objects.end());
cerr << "- " << *p << std::endl;
//cerr << " objects_set: " << objects_set << std::endl;
//cerr << " available_set: " << available_objects << std::endl;
- assert(0 == "badness");
+ ceph_abort_msg("badness");
}
ASSERT_EQ(objects_set.size(), available_objects.size());
ASSERT_GT(available_objects.count(*i), (unsigned)0);
}
- int r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
- INT_MAX, &objects, 0);
+ int r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(),
+ INT_MAX, &objects, 0);
ASSERT_EQ(r, 0);
objects_set2.insert(objects.begin(), objects.end());
ASSERT_EQ(objects_set2.size(), available_objects.size());
ghobject_t hoid;
uint64_t expected;
{
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("stat lock1");
if (!can_unlink())
return ;
- hoid = get_uniform_random_object();
+ hoid = get_uniform_random_object(locker);
in_flight_objects.insert(hoid);
available_objects.erase(hoid);
++in_flight;
expected = contents[hoid].data.length();
}
struct stat buf;
- int r = store->stat(cid, hoid, &buf);
+ int r = store->stat(ch, hoid, &buf);
ASSERT_EQ(0, r);
- assert((uint64_t)buf.st_size == expected);
+ ceph_assert((uint64_t)buf.st_size == expected);
ASSERT_TRUE((uint64_t)buf.st_size == expected);
{
- Mutex::Locker locker(lock);
+ std::lock_guard locker{lock};
EnterExit ee("stat lock2");
--in_flight;
- cond.Signal();
+ cond.notify_all();
in_flight_objects.erase(hoid);
available_objects.insert(hoid);
}
}
int unlink() {
- Mutex::Locker locker(lock);
+ std::unique_lock locker{lock};
EnterExit ee("unlink");
if (!can_unlink())
return -ENOENT;
- ghobject_t to_remove = get_uniform_random_object();
+ ghobject_t to_remove = get_uniform_random_object(locker);
ObjectStore::Transaction t;
t.remove(cid, to_remove);
++in_flight;
available_objects.erase(to_remove);
in_flight_objects.insert(to_remove);
contents.erase(to_remove);
- int status = store->queue_transaction(osr, std::move(t), new C_SyntheticOnReadable(this, to_remove));
+ t.register_on_applied(new C_SyntheticOnReadable(this, to_remove));
+ int status = store->queue_transaction(ch, std::move(t));
return status;
}
void print_internal_state() {
- Mutex::Locker locker(lock);
+ std::lock_guard locker{lock};
cerr << "available_objects: " << available_objects.size()
<< " in_flight_objects: " << in_flight_objects.size()
<< " total objects: " << in_flight_objects.size() + available_objects.size()
};
-void doSyntheticTest(boost::scoped_ptr<ObjectStore>& store,
+void StoreTest::doSyntheticTest(
int num_ops,
uint64_t max_obj, uint64_t max_wr, uint64_t align)
{
- ObjectStore::Sequencer osr("test");
MixedGenerator gen(555);
gen_type rng(time(NULL));
coll_t cid(spg_t(pg_t(0,555), shard_id_t::NO_SHARD));
- g_ceph_context->_conf->set_val("bluestore_fsck_on_mount", "false");
- g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "false");
- g_ceph_context->_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_fsck_on_mount", "false");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "false");
+ g_ceph_context->_conf.apply_changes(nullptr);
- SyntheticWorkloadState test_obj(store.get(), &gen, &rng, &osr, cid,
+ SyntheticWorkloadState test_obj(store.get(), &gen, &rng, cid,
max_obj, max_wr, align);
test_obj.init();
for (int i = 0; i < num_ops/10; ++i) {
}
test_obj.wait_for_done();
test_obj.shutdown();
-
- g_ceph_context->_conf->set_val("bluestore_fsck_on_mount", "true");
- g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "true");
- g_ceph_context->_conf->apply_changes(NULL);
}
TEST_P(StoreTest, Synthetic) {
- doSyntheticTest(store, 10000, 400*1024, 40*1024, 0);
+ doSyntheticTest(10000, 400*1024, 40*1024, 0);
+}
+
+#if defined(WITH_BLUESTORE)
+TEST_P(StoreTestSpecificAUSize, BlueFSExtenderTest) {
+ if(string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_db_size", "0");
+ SetVal(g_conf(), "bluestore_block_wal_size", "0");
+ SetVal(g_conf(), "bluestore_bluefs_min", "12582912");
+ SetVal(g_conf(), "bluestore_bluefs_min_free", "4194304");
+ SetVal(g_conf(), "bluestore_bluefs_gift_ratio", "0");
+ SetVal(g_conf(), "bluestore_bluefs_min_ratio", "0");
+ SetVal(g_conf(), "bluestore_bluefs_balance_interval", "100000");
+ SetVal(g_conf(), "bluestore_bluefs_db_compatibility", "false");
+
+ g_conf().apply_changes(nullptr);
+
+ StartDeferred(4096);
+
+ doSyntheticTest(10000, 400*1024, 40*1024, 0);
+
+ BlueStore* bstore = NULL;
+ EXPECT_NO_THROW(bstore = dynamic_cast<BlueStore*> (store.get()));
+
+ // verify downgrades are broken and repair that
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 0);
+
+ SetVal(g_conf(), "bluestore_bluefs_db_compatibility", "true");
+ g_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(StoreTestSpecificAUSize, SyntheticMatrixSharding) {
if (string(GetParam()) != "bluestore")
return;
{ "bluestore_default_buffered_write", "true", 0 },
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
TEST_P(StoreTestSpecificAUSize, ZipperPatternSharded) {
StartDeferred(4096);
int r;
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t a(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist bl;
for (int i=0; i<1000; ++i) {
ObjectStore::Transaction t;
t.write(cid, a, i*2*len, len, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
for (int i=0; i<1000; ++i) {
ObjectStore::Transaction t;
t.write(cid, a, i*2*len + 1, len, bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.remove(cid, a);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
{ "bluestore_default_buffered_write", "false", 0 },
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
TEST_P(StoreTestSpecificAUSize, SyntheticMatrixCsumVsCompression) {
{ "bluestore_sync_submit_transaction", "false", 0 },
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
TEST_P(StoreTestSpecificAUSize, SyntheticMatrixCompression) {
{ "bluestore_sync_submit_transaction", "true", 0 },
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
TEST_P(StoreTestSpecificAUSize, SyntheticMatrixCompressionAlgorithm) {
{ "bluestore_default_buffered_write", "false", 0 },
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
TEST_P(StoreTestSpecificAUSize, SyntheticMatrixNoCsum) {
{ "bluestore_sync_submit_transaction", "true", "false", 0 },
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
TEST_P(StoreTestSpecificAUSize, SyntheticMatrixPreferDeferred) {
{ "bluestore_prefer_deferred_size", "32768", "0", 0},
{ 0 },
};
- do_matrix(m, store, doSyntheticTest);
+ do_matrix(m, std::bind(&StoreTest::doSyntheticTest, this, _1, _2, _3, _4));
}
+#endif // WITH_BLUESTORE
TEST_P(StoreTest, AttrSynthetic) {
- ObjectStore::Sequencer osr("test");
MixedGenerator gen(447);
gen_type rng(time(NULL));
coll_t cid(spg_t(pg_t(0,447),shard_id_t::NO_SHARD));
- SyntheticWorkloadState test_obj(store.get(), &gen, &rng, &osr, cid, 40*1024, 4*1024, 0);
+ SyntheticWorkloadState test_obj(store.get(), &gen, &rng, cid, 40*1024, 4*1024, 0);
test_obj.init();
for (int i = 0; i < 500; ++i) {
if (!(i % 10)) cerr << "seeding object " << i << std::endl;
}
TEST_P(StoreTest, HashCollisionTest) {
- ObjectStore::Sequencer osr("test");
int64_t poolid = 11;
coll_t cid(spg_t(pg_t(0,poolid),shard_id_t::NO_SHARD));
int r;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
string base = "";
{
ObjectStore::Transaction t;
t.touch(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
created.insert(hoid);
}
}
vector<ghobject_t> objects;
- r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(), INT_MAX, &objects, 0);
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
ASSERT_EQ(r, 0);
set<ghobject_t> listed(objects.begin(), objects.end());
cerr << "listed.size() is " << listed.size() << " and created.size() is " << created.size() << std::endl;
listed.clear();
ghobject_t current, next;
while (1) {
- r = store->collection_list(cid, current, ghobject_t::get_max(), 60,
- &objects, &next);
+ r = collection_list(store, ch, current, ghobject_t::get_max(), 60, &objects,
+ &next);
ASSERT_EQ(r, 0);
ASSERT_TRUE(sorted(objects));
for (vector<ghobject_t>::iterator i = objects.begin();
++i) {
ObjectStore::Transaction t;
t.remove(cid, *i);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectStore::Transaction t;
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+}
+
+TEST_P(StoreTest, HashCollisionSorting) {
+ bool disable_legacy = (string(GetParam()) == "bluestore");
+
+ char buf121664318_1[] = {18, -119, -121, -111, 0};
+ char buf121664318_2[] = {19, 127, -121, 32, 0};
+ char buf121664318_3[] = {19, -118, 15, 19, 0};
+ char buf121664318_4[] = {28, 27, -116, -113, 0};
+ char buf121664318_5[] = {28, 27, -115, -124, 0};
+
+ char buf121666222_1[] = {18, -119, -120, -111, 0};
+ char buf121666222_2[] = {19, 127, -120, 32, 0};
+ char buf121666222_3[] = {19, -118, 15, 30, 0};
+ char buf121666222_4[] = {29, 17, -126, -113, 0};
+ char buf121666222_5[] = {29, 17, -125, -124, 0};
+
+ std::map<uint32_t, std::vector<std::string>> object_names = {
+ {121664318, {{buf121664318_1},
+ {buf121664318_2},
+ {buf121664318_3},
+ {buf121664318_4},
+ {buf121664318_5}}},
+ {121666222, {{buf121666222_1},
+ {buf121666222_2},
+ {buf121666222_3},
+ {buf121666222_4},
+ {buf121666222_5}}}};
+
+ int64_t poolid = 111;
+ coll_t cid = coll_t(spg_t(pg_t(0, poolid), shard_id_t::NO_SHARD));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ int r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ std::set<ghobject_t> created;
+ for (auto &[hash, names] : object_names) {
+ for (auto &name : names) {
+ ghobject_t hoid(hobject_t(sobject_t(name, CEPH_NOSNAP),
+ string(),
+ hash,
+ poolid,
+ string()));
+ ASSERT_EQ(hash, hoid.hobj.get_hash());
+ ObjectStore::Transaction t;
+ t.touch(cid, hoid);
+ int r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ created.insert(hoid);
+ }
+ }
+
+ vector<ghobject_t> objects;
+ int r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(),
+ INT_MAX, &objects, 0, disable_legacy);
ASSERT_EQ(r, 0);
+ ASSERT_EQ(created.size(), objects.size());
+ auto it = objects.begin();
+ for (auto &hoid : created) {
+ ASSERT_EQ(hoid, *it);
+ it++;
+ }
+
+ for (auto i = created.begin(); i != created.end(); i++) {
+ auto j = i;
+ for (j++; j != created.end(); j++) {
+ std::set<ghobject_t> created_sub(i, j);
+ objects.clear();
+ ghobject_t next;
+ r = collection_list(store, ch, *i, ghobject_t::get_max(),
+ created_sub.size(), &objects, &next, disable_legacy);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(created_sub.size(), objects.size());
+ it = objects.begin();
+ for (auto &hoid : created_sub) {
+ ASSERT_EQ(hoid, *it);
+ it++;
+ }
+ if (j == created.end()) {
+ ASSERT_TRUE(next.is_max());
+ } else {
+ ASSERT_EQ(*j, next);
+ }
+ }
+ }
+
+ for (auto i = created.begin(); i != created.end(); i++) {
+ auto j = i;
+ for (j++; j != created.end(); j++) {
+ std::set<ghobject_t> created_sub(i, j);
+ objects.clear();
+ ghobject_t next;
+ r = collection_list(store, ch, *i, *j, INT_MAX, &objects, &next,
+ disable_legacy);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(created_sub.size(), objects.size());
+ it = objects.begin();
+ for (auto &hoid : created_sub) {
+ ASSERT_EQ(hoid, *it);
+ it++;
+ }
+ if (j == created.end()) {
+ ASSERT_TRUE(next.is_max());
+ } else {
+ ASSERT_EQ(*j, next);
+ }
+ }
+ }
}
TEST_P(StoreTest, ScrubTest) {
- ObjectStore::Sequencer osr("test");
int64_t poolid = 111;
coll_t cid(spg_t(pg_t(0, poolid),shard_id_t(1)));
int r;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
string base = "aaaaa";
{
ObjectStore::Transaction t;
t.touch(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
created.insert(hoid);
t.touch(cid, hoid1);
t.touch(cid, hoid2);
t.touch(cid, hoid3);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
created.insert(hoid1);
created.insert(hoid2);
created.insert(hoid3);
}
vector<ghobject_t> objects;
- r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
- INT_MAX, &objects, 0);
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
ASSERT_EQ(r, 0);
set<ghobject_t> listed(objects.begin(), objects.end());
cerr << "listed.size() is " << listed.size() << " and created.size() is " << created.size() << std::endl;
listed.clear();
ghobject_t current, next;
while (1) {
- r = store->collection_list(cid, current, ghobject_t::get_max(), 60,
- &objects, &next);
+ r = collection_list(store, ch, current, ghobject_t::get_max(), 60, &objects,
+ &next);
ASSERT_EQ(r, 0);
ASSERT_TRUE(sorted(objects));
for (vector<ghobject_t>::iterator i = objects.begin();
++i) {
ObjectStore::Transaction t;
t.remove(cid, *i);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectStore::Transaction t;
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
TEST_P(StoreTest, OMapTest) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t("tesomap", "", CEPH_NOSNAP, 0, 0, ""));
+ auto ch = store->create_new_collection(cid);
int r;
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
t.omap_clear(cid, hoid);
map<string, bufferlist> start_set;
t.omap_setkeys(cid, hoid, start_set);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectStore::Transaction t;
bufferlist bl;
map<string, bufferlist> cur_attrs;
- r = store->omap_get(cid, hoid, &bl, &cur_attrs);
+ r = store->omap_get(ch, hoid, &bl, &cur_attrs);
ASSERT_EQ(r, 0);
for (map<string, bufferlist>::iterator j = attrs.begin();
j != attrs.end();
to_add.insert(pair<string, bufferlist>("key-" + string(buf), bl));
attrs.insert(pair<string, bufferlist>("key-" + string(buf), bl));
t.omap_setkeys(cid, hoid, to_add);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectStore::Transaction t;
bufferlist bl;
map<string, bufferlist> cur_attrs;
- r = store->omap_get(cid, hoid, &bl, &cur_attrs);
+ r = store->omap_get(ch, hoid, &bl, &cur_attrs);
ASSERT_EQ(r, 0);
for (map<string, bufferlist>::iterator j = attrs.begin();
j != attrs.end();
}
string to_remove = attrs.begin()->first;
- set<string> keys_to_remove;
- keys_to_remove.insert(to_remove);
- t.omap_rmkeys(cid, hoid, keys_to_remove);
- r = apply_transaction(store, &osr, std::move(t));
+ t.omap_rmkey(cid, hoid, to_remove);
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
attrs.erase(to_remove);
bl1.append("omap_header");
ObjectStore::Transaction t;
t.omap_setheader(cid, hoid, bl1);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
t = ObjectStore::Transaction();
map<string, bufferlist> to_add;
to_add.insert(pair<string, bufferlist>("key", bl2));
t.omap_setkeys(cid, hoid, to_add);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bufferlist bl3;
map<string, bufferlist> cur_attrs;
- r = store->omap_get(cid, hoid, &bl3, &cur_attrs);
+ r = store->omap_get(ch, hoid, &bl3, &cur_attrs);
ASSERT_EQ(r, 0);
ASSERT_EQ(cur_attrs.size(), size_t(1));
ASSERT_TRUE(bl_eq(bl1, bl3));
set<string> keys;
- r = store->omap_get_keys(cid, hoid, &keys);
+ r = store->omap_get_keys(ch, hoid, &keys);
ASSERT_EQ(r, 0);
ASSERT_EQ(keys.size(), size_t(1));
}
t.touch(cid, hoid);
t.omap_setheader(cid, hoid, h);
t.omap_setkeys(cid, hoid, to_set);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.omap_rmkeyrange(cid, hoid, "3", "7");
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bufferlist hdr;
map<string,bufferlist> m;
- store->omap_get(cid, hoid, &hdr, &m);
+ store->omap_get(ch, hoid, &hdr, &m);
ASSERT_EQ(6u, hdr.length());
ASSERT_TRUE(m.count("2"));
ASSERT_TRUE(!m.count("3"));
{
ObjectStore::Transaction t;
t.omap_clear(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bufferlist hdr;
map<string,bufferlist> m;
- store->omap_get(cid, hoid, &hdr, &m);
+ store->omap_get(ch, hoid, &hdr, &m);
ASSERT_EQ(0u, hdr.length());
ASSERT_EQ(0u, m.size());
}
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
TEST_P(StoreTest, OMapIterator) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t("tesomap", "", CEPH_NOSNAP, 0, 0, ""));
int count = 0;
+ auto ch = store->create_new_collection(cid);
int r;
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
t.omap_clear(cid, hoid);
map<string, bufferlist> start_set;
t.omap_setkeys(cid, hoid, start_set);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectMap::ObjectMapIterator iter;
// FileStore may deadlock two active iterators over the same data
iter = ObjectMap::ObjectMapIterator();
- iter = store->get_omap_iterator(cid, hoid);
+ iter = store->get_omap_iterator(ch, hoid);
for (iter->seek_to_first(), count=0; iter->valid(); iter->next(), count++) {
string key = iter->key();
bufferlist value = iter->value();
}
ASSERT_EQ((int)attrs.size(), count);
- // FileStore may deadlock an active iterator vs apply_transaction
+ // FileStore may deadlock an active iterator vs queue_transaction
iter = ObjectMap::ObjectMapIterator();
char buf[100];
attrs.insert(pair<string, bufferlist>("key-" + string(buf), bl));
ObjectStore::Transaction t;
t.omap_setkeys(cid, hoid, to_add);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- iter = store->get_omap_iterator(cid, hoid);
+ iter = store->get_omap_iterator(ch, hoid);
//lower bound
string bound_key = "key-5";
iter->lower_bound(bound_key);
}
ASSERT_EQ(correct, true);
- // FileStore may deadlock an active iterator vs apply_transaction
+ // FileStore may deadlock an active iterator vs queue_transaction
iter = ObjectMap::ObjectMapIterator();
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, XattrTest) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t("tesomap", "", CEPH_NOSNAP, 0, 0, ""));
bufferlist big;
small.append('\0');
}
int r;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
attrs["attr4"] = big;
t.setattr(cid, hoid, "attr3", big);
attrs["attr3"] = big;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
map<string, bufferptr> aset;
- store->getattrs(cid, hoid, aset);
+ store->getattrs(ch, hoid, aset);
ASSERT_EQ(aset.size(), attrs.size());
for (map<string, bufferptr>::iterator i = aset.begin();
i != aset.end();
ObjectStore::Transaction t;
t.rmattr(cid, hoid, "attr2");
attrs.erase("attr2");
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
aset.clear();
- store->getattrs(cid, hoid, aset);
+ store->getattrs(ch, hoid, aset);
ASSERT_EQ(aset.size(), attrs.size());
for (map<string, bufferptr>::iterator i = aset.begin();
i != aset.end();
}
bufferptr bp;
- r = store->getattr(cid, hoid, "attr2", bp);
+ r = store->getattr(ch, hoid, "attr2", bp);
ASSERT_EQ(r, -ENODATA);
- r = store->getattr(cid, hoid, "attr3", bp);
+ r = store->getattr(ch, hoid, "attr3", bp);
ASSERT_EQ(r, 0);
bufferlist bl2;
bl2.push_back(bp);
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
unsigned common_suffix_size,
bool clones
) {
- ObjectStore::Sequencer osr("test");
coll_t cid(spg_t(pg_t(0,52),shard_id_t::NO_SHARD));
coll_t tid(spg_t(pg_t(1<<common_suffix_size,52),shard_id_t::NO_SHARD));
+ auto ch = store->create_new_collection(cid);
+ auto tch = store->create_new_collection(tid);
int r = 0;
{
ObjectStore::Transaction t;
t.create_collection(cid, common_suffix_size);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
bufferlist small;
t.clone(cid, a, b);
}
if (i % 100) {
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
t = ObjectStore::Transaction();
}
}
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.create_collection(tid, common_suffix_size + 1);
t.split_collection(cid, common_suffix_size+1, 1<<common_suffix_size, tid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
+ ch->flush();
- ObjectStore::Transaction t;
+ // check
vector<ghobject_t> objects;
- r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
- INT_MAX, &objects, 0);
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
ASSERT_EQ(r, 0);
ASSERT_EQ(objects.size(), num_objects);
- unsigned size = 0;
for (vector<ghobject_t>::iterator i = objects.begin();
i != objects.end();
++i) {
ASSERT_EQ(!!(i->hobj.get_hash() & (1<<common_suffix_size)), 0u);
- t.remove(cid, *i);
- if (++size > 100) {
- size = 0;
- r = apply_transaction(store, &osr, std::move(t));
- ASSERT_EQ(r, 0);
- t = ObjectStore::Transaction();
- }
}
objects.clear();
- r = store->collection_list(tid, ghobject_t(), ghobject_t::get_max(),
- INT_MAX, &objects, 0);
+ r = collection_list(store, tch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
ASSERT_EQ(r, 0);
ASSERT_EQ(objects.size(), num_objects);
for (vector<ghobject_t>::iterator i = objects.begin();
i != objects.end();
++i) {
ASSERT_EQ(!(i->hobj.get_hash() & (1<<common_suffix_size)), 0u);
- t.remove(tid, *i);
- if (++size > 100) {
- size = 0;
- r = apply_transaction(store, &osr, std::move(t));
- ASSERT_EQ(r, 0);
- t = ObjectStore::Transaction();
- }
}
+ // merge them again!
+ {
+ ObjectStore::Transaction t;
+ t.merge_collection(tid, cid, common_suffix_size);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ // check and clean up
+ ObjectStore::Transaction t;
+ {
+ vector<ghobject_t> objects;
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(objects.size(), num_objects * 2); // both halves
+ unsigned size = 0;
+ for (vector<ghobject_t>::iterator i = objects.begin();
+ i != objects.end();
+ ++i) {
+ t.remove(cid, *i);
+ if (++size > 100) {
+ size = 0;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ t = ObjectStore::Transaction();
+ }
+ }
+ }
t.remove_collection(cid);
- t.remove_collection(tid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
+
+ ch->flush();
+ ASSERT_TRUE(!store->collection_exists(tid));
}
+TEST_P(StoreTest, ColSplitTest0) {
+ colsplittest(store.get(), 10, 5, false);
+}
TEST_P(StoreTest, ColSplitTest1) {
colsplittest(store.get(), 10000, 11, false);
}
}
#endif
+void test_merge_skewed(ObjectStore *store,
+ unsigned base, unsigned bits,
+ unsigned anum, unsigned bnum)
+{
+ cout << __func__ << " 0x" << std::hex << base << std::dec
+ << " bits " << bits
+ << " anum " << anum << " bnum " << bnum << std::endl;
+ /*
+ make merge source pgs have radically different # of objects in them,
+ which should trigger different splitting in filestore, and verify that
+ post-merge all objects are accessible.
+ */
+ int r;
+ coll_t a(spg_t(pg_t(base, 0), shard_id_t::NO_SHARD));
+ coll_t b(spg_t(pg_t(base | (1<<bits), 0), shard_id_t::NO_SHARD));
+
+ auto cha = store->create_new_collection(a);
+ auto chb = store->create_new_collection(b);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(a, bits + 1);
+ r = queue_transaction(store, cha, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(b, bits + 1);
+ r = queue_transaction(store, chb, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ bufferlist small;
+ small.append("small");
+ string suffix = "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooaaaaaaaaaa";
+ set<ghobject_t> aobjects, bobjects;
+ {
+ // fill a
+ ObjectStore::Transaction t;
+ for (unsigned i = 0; i < 1000; ++i) {
+ string objname = "a" + stringify(i) + suffix;
+ ghobject_t o(hobject_t(
+ objname,
+ "",
+ CEPH_NOSNAP,
+ i<<(bits+1) | base,
+ 52, ""));
+ aobjects.insert(o);
+ t.write(a, o, 0, small.length(), small, 0);
+ if (i % 100) {
+ r = queue_transaction(store, cha, std::move(t));
+ ASSERT_EQ(r, 0);
+ t = ObjectStore::Transaction();
+ }
+ }
+ r = queue_transaction(store, cha, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ // fill b
+ ObjectStore::Transaction t;
+ for (unsigned i = 0; i < 10; ++i) {
+ string objname = "b" + stringify(i) + suffix;
+ ghobject_t o(hobject_t(
+ objname,
+ "",
+ CEPH_NOSNAP,
+ (i<<(base+1)) | base | (1<<bits),
+ 52, ""));
+ bobjects.insert(o);
+ t.write(b, o, 0, small.length(), small, 0);
+ if (i % 100) {
+ r = queue_transaction(store, chb, std::move(t));
+ ASSERT_EQ(r, 0);
+ t = ObjectStore::Transaction();
+ }
+ }
+ r = queue_transaction(store, chb, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ // merge b->a
+ {
+ ObjectStore::Transaction t;
+ t.merge_collection(b, a, bits);
+ r = queue_transaction(store, cha, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ // verify
+ {
+ vector<ghobject_t> got;
+ collection_list(store, cha, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &got, 0);
+ set<ghobject_t> gotset;
+ for (auto& o : got) {
+ ASSERT_TRUE(aobjects.count(o) || bobjects.count(o));
+ gotset.insert(o);
+ }
+ // check both listing and stat-ability (different code paths!)
+ struct stat st;
+ for (auto& o : aobjects) {
+ ASSERT_TRUE(gotset.count(o));
+ int r = store->stat(cha, o, &st, false);
+ ASSERT_EQ(r, 0);
+ }
+ for (auto& o : bobjects) {
+ ASSERT_TRUE(gotset.count(o));
+ int r = store->stat(cha, o, &st, false);
+ ASSERT_EQ(r, 0);
+ }
+ }
+
+ // clean up
+ {
+ ObjectStore::Transaction t;
+ for (auto &o : aobjects) {
+ t.remove(a, o);
+ }
+ r = queue_transaction(store, cha, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ for (auto &o : bobjects) {
+ t.remove(a, o);
+ }
+ t.remove_collection(a);
+ r = queue_transaction(store, cha, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+}
+
+TEST_P(StoreTest, MergeSkewed) {
+ if (string(GetParam()) != "filestore")
+ return;
+
+ // this is sufficient to exercise merges with different hashing levels
+ test_merge_skewed(store.get(), 0xf, 4, 10, 10000);
+ test_merge_skewed(store.get(), 0xf, 4, 10000, 10);
+
+ /*
+ // this covers a zillion variations that all boil down to the same thing
+ for (unsigned base = 3; base < 0x1000; base *= 5) {
+ unsigned bits;
+ unsigned t = base;
+ for (bits = 0; t; t >>= 1) {
+ ++bits;
+ }
+ for (unsigned b = bits; b < bits + 10; b += 3) {
+ for (auto anum : { 10, 1000, 10000 }) {
+ for (auto bnum : { 10, 1000, 10000 }) {
+ if (anum == bnum) {
+ continue;
+ }
+ test_merge_skewed(store.get(), base, b, anum, bnum);
+ }
+ }
+ }
+ }
+ */
+}
+
+
/**
* This test tests adding two different groups
* of objects, each with 1 common prefix and 1
* stops at the common prefix subdir. See bug
* #5273 */
TEST_P(StoreTest, TwoHash) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
int r;
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
std::cout << "Making objects" << std::endl;
}
o.hobj.set_hash((i << 16) | 0xB1);
t.touch(cid, o);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
std::cout << "Removing half" << std::endl;
o.hobj.pool = -1;
o.hobj.set_hash((i << 16) | 0xA1);
t.remove(cid, o);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
std::cout << "Checking" << std::endl;
ghobject_t o;
o.hobj.set_hash((i << 16) | 0xA1);
o.hobj.pool = -1;
- bool exists = store->exists(cid, o);
+ bool exists = store->exists(ch, o);
ASSERT_EQ(exists, false);
}
{
ghobject_t o;
o.hobj.set_hash(0xA1);
o.hobj.pool = -1;
- bool exists = store->exists(cid, o);
+ bool exists = store->exists(ch, o);
ASSERT_EQ(exists, true);
}
std::cout << "Cleanup" << std::endl;
t.remove(cid, o);
o.hobj.set_hash((i << 16) | 0xB1);
t.remove(cid, o);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectStore::Transaction t;
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
TEST_P(StoreTest, Rename) {
- ObjectStore::Sequencer osr("test");
coll_t cid(spg_t(pg_t(0, 2122),shard_id_t::NO_SHARD));
ghobject_t srcoid(hobject_t("src_oid", "", CEPH_NOSNAP, 0, 0, ""));
ghobject_t dstoid(hobject_t("dest_oid", "", CEPH_NOSNAP, 0, 0, ""));
bufferlist a, b;
a.append("foo");
b.append("bar");
+ auto ch = store->create_new_collection(cid);
int r;
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.write(cid, srcoid, 0, a.length(), a);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- ASSERT_TRUE(store->exists(cid, srcoid));
+ ASSERT_TRUE(store->exists(ch, srcoid));
{
ObjectStore::Transaction t;
t.collection_move_rename(cid, srcoid, cid, dstoid);
t.write(cid, srcoid, 0, b.length(), b);
t.setattr(cid, srcoid, "attr", b);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- ASSERT_TRUE(store->exists(cid, srcoid));
- ASSERT_TRUE(store->exists(cid, dstoid));
+ ASSERT_TRUE(store->exists(ch, srcoid));
+ ASSERT_TRUE(store->exists(ch, dstoid));
{
bufferlist bl;
- store->read(cid, srcoid, 0, 3, bl);
+ store->read(ch, srcoid, 0, 3, bl);
ASSERT_TRUE(bl_eq(b, bl));
- store->read(cid, dstoid, 0, 3, bl);
+ store->read(ch, dstoid, 0, 3, bl);
ASSERT_TRUE(bl_eq(a, bl));
}
{
ObjectStore::Transaction t;
t.remove(cid, dstoid);
t.collection_move_rename(cid, srcoid, cid, dstoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- ASSERT_TRUE(store->exists(cid, dstoid));
- ASSERT_FALSE(store->exists(cid, srcoid));
+ ASSERT_TRUE(store->exists(ch, dstoid));
+ ASSERT_FALSE(store->exists(ch, srcoid));
{
bufferlist bl;
- store->read(cid, dstoid, 0, 3, bl);
+ store->read(ch, dstoid, 0, 3, bl);
ASSERT_TRUE(bl_eq(b, bl));
}
{
ObjectStore::Transaction t;
t.remove(cid, dstoid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, MoveRename) {
- ObjectStore::Sequencer osr("test");
coll_t cid(spg_t(pg_t(0, 212),shard_id_t::NO_SHARD));
ghobject_t temp_oid(hobject_t("tmp_oid", "", CEPH_NOSNAP, 0, 0, ""));
ghobject_t oid(hobject_t("dest_oid", "", CEPH_NOSNAP, 0, 0, ""));
+ auto ch = store->create_new_collection(cid);
int r;
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, oid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- ASSERT_TRUE(store->exists(cid, oid));
+ ASSERT_TRUE(store->exists(ch, oid));
bufferlist data, attr;
map<string, bufferlist> omap;
data.append("data payload");
t.write(cid, temp_oid, 0, data.length(), data);
t.setattr(cid, temp_oid, "attr", attr);
t.omap_setkeys(cid, temp_oid, omap);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- ASSERT_TRUE(store->exists(cid, temp_oid));
+ ASSERT_TRUE(store->exists(ch, temp_oid));
{
ObjectStore::Transaction t;
t.remove(cid, oid);
t.collection_move_rename(cid, temp_oid, cid, oid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- ASSERT_TRUE(store->exists(cid, oid));
- ASSERT_FALSE(store->exists(cid, temp_oid));
+ ASSERT_TRUE(store->exists(ch, oid));
+ ASSERT_FALSE(store->exists(ch, temp_oid));
{
bufferlist newdata;
- r = store->read(cid, oid, 0, 1000, newdata);
+ r = store->read(ch, oid, 0, 1000, newdata);
ASSERT_GE(r, 0);
ASSERT_TRUE(bl_eq(data, newdata));
bufferlist newattr;
- r = store->getattr(cid, oid, "attr", newattr);
+ r = store->getattr(ch, oid, "attr", newattr);
ASSERT_EQ(r, 0);
ASSERT_TRUE(bl_eq(attr, newattr));
set<string> keys;
keys.insert("omap_key");
map<string, bufferlist> newomap;
- r = store->omap_get_values(cid, oid, keys, &newomap);
+ r = store->omap_get_values(ch, oid, keys, &newomap);
ASSERT_GE(r, 0);
ASSERT_EQ(1u, newomap.size());
ASSERT_TRUE(newomap.count("omap_key"));
ObjectStore::Transaction t;
t.remove(cid, oid);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, BigRGWObjectName) {
- ObjectStore::Sequencer osr("test");
coll_t cid(spg_t(pg_t(0,12),shard_id_t::NO_SHARD));
ghobject_t oid(
hobject_t(
ghobject_t oidhead(oid);
oidhead.generation = ghobject_t::NO_GEN;
+ auto ch = store->create_new_collection(cid);
+
int r;
{
ObjectStore::Transaction t;
t.collection_move_rename(cid, oidhead, cid, oid);
t.touch(cid, oidhead);
t.collection_move_rename(cid, oidhead, cid, oid2);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove(cid, oid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
vector<ghobject_t> objects;
- r = store->collection_list(cid, ghobject_t(), ghobject_t::get_max(),
- INT_MAX, &objects, 0);
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, 0);
ASSERT_EQ(r, 0);
ASSERT_EQ(objects.size(), 1u);
ASSERT_EQ(objects[0], oid2);
}
- ASSERT_FALSE(store->exists(cid, oid));
+ ASSERT_FALSE(store->exists(ch, oid));
{
ObjectStore::Transaction t;
t.remove(cid, oid2);
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, SetAllocHint) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, 0, ""));
+ auto ch = store->create_new_collection(cid);
int r;
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
t.touch(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*4, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*4, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.remove_collection(cid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
TEST_P(StoreTest, TryMoveRename) {
- ObjectStore::Sequencer osr("test");
coll_t cid;
ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
ghobject_t hoid2(hobject_t("test_hint2", "", CEPH_NOSNAP, 0, -1, ""));
+ auto ch = store->create_new_collection(cid);
int r;
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.try_rename(cid, hoid, hoid2);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.touch(cid, hoid);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
ObjectStore::Transaction t;
t.try_rename(cid, hoid, hoid2);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
struct stat st;
- ASSERT_EQ(store->stat(cid, hoid, &st), -ENOENT);
- ASSERT_EQ(store->stat(cid, hoid2, &st), 0);
+ ASSERT_EQ(store->stat(ch, hoid, &st), -ENOENT);
+ ASSERT_EQ(store->stat(ch, hoid2, &st), 0);
}
-#if defined(HAVE_LIBAIO)
+#if defined(WITH_BLUESTORE)
TEST_P(StoreTest, BluestoreOnOffCSumTest) {
if (string(GetParam()) != "bluestore")
return;
- g_conf->set_val("bluestore_csum_type", "crc32c");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "crc32c");
+ g_conf().apply_changes(nullptr);
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
{
- bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
- ASSERT_EQ(-ENOENT, r);
+ auto ch = store->open_collection(cid);
+ ASSERT_FALSE(ch);
}
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*8, 0);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "Remove then create" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- g_conf->set_val("bluestore_csum_type", "none");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "none");
+ g_conf().apply_changes(nullptr);
bufferlist in;
- r = store->read(cid, hoid, 0, block_size, in);
+ r = store->read(ch, hoid, 0, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*8, 0);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "Remove then create" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- g_conf->set_val("bluestore_csum_type", "crc32c");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "crc32c");
+ g_conf().apply_changes(nullptr);
bufferlist in;
- r = store->read(cid, hoid, 0, block_size, in);
+ r = store->read(ch, hoid, 0, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
}
t.remove(cid, hoid);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "Remove then create" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- g_conf->set_val("bluestore_csum_type", "none");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "none");
+ g_conf().apply_changes(nullptr);
ObjectStore::Transaction t2;
t2.write(cid, hoid, block_size*2, bl.length(), bl);
cerr << "Append 'unprotected'" << std::endl;
- r = apply_transaction(store, &osr, std::move(t2));
+ r = queue_transaction(store, ch, std::move(t2));
ASSERT_EQ(r, 0);
bufferlist in;
- r = store->read(cid, hoid, 0, block_size, in);
+ r = store->read(ch, hoid, 0, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
in.clear();
- r = store->read(cid, hoid, block_size*2, block_size, in);
+ r = store->read(ch, hoid, block_size*2, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
- g_conf->set_val("bluestore_csum_type", "crc32c");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "crc32c");
+ g_conf().apply_changes(nullptr);
in.clear();
- r = store->read(cid, hoid, 0, block_size, in);
+ r = store->read(ch, hoid, 0, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
in.clear();
- r = store->read(cid, hoid, block_size*2, block_size, in);
+ r = store->read(ch, hoid, block_size*2, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
}
t.set_alloc_hint(cid, hoid, 4*1024*1024, 1024*8, 0);
t.write(cid, hoid, 0, bl.length(), bl);
cerr << "Remove then create" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- g_conf->set_val("bluestore_csum_type", "none");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "none");
+ g_conf().apply_changes(nullptr);
ObjectStore::Transaction t2;
bl.clear();
t2.write(cid, hoid, 0, bl.length(), bl);
t2.write(cid, hoid, block_size0, bl.length(), bl);
cerr << "Overwrite with unprotected data" << std::endl;
- r = apply_transaction(store, &osr, std::move(t2));
+ r = queue_transaction(store, ch, std::move(t2));
ASSERT_EQ(r, 0);
orig = bl;
orig.append( std::string(block_size0 - block_size, 'a'));
bufferlist in;
- r = store->read(cid, hoid, 0, block_size0, in);
+ r = store->read(ch, hoid, 0, block_size0, in);
ASSERT_EQ((int)block_size0, r);
ASSERT_TRUE(bl_eq(orig, in));
- r = store->read(cid, hoid, block_size0, block_size, in);
+ r = store->read(ch, hoid, block_size0, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig2, in));
- g_conf->set_val("bluestore_csum_type", "crc32c");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_csum_type", "crc32c");
+ g_conf().apply_changes(nullptr);
ObjectStore::Transaction t3;
bl.clear();
bl.append(std::string(block_size2, 'c'));
t3.write(cid, hoid, block_size0, bl.length(), bl);
cerr << "Overwrite with protected data" << std::endl;
- r = apply_transaction(store, &osr, std::move(t3));
+ r = queue_transaction(store, ch, std::move(t3));
ASSERT_EQ(r, 0);
in.clear();
orig = bl;
orig.append( std::string(block_size - block_size2, 'b'));
- r = store->read(cid, hoid, block_size0, block_size, in);
+ r = store->read(ch, hoid, block_size0, block_size, in);
ASSERT_EQ((int)block_size, r);
ASSERT_TRUE(bl_eq(orig, in));
}
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
#endif
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ObjectStore,
StoreTest,
::testing::Values(
"memstore",
"filestore",
-#if defined(HAVE_LIBAIO)
+#if defined(WITH_BLUESTORE)
"bluestore",
#endif
"kstore"));
// Note: instantiate all stores to preserve store numbering order only
-INSTANTIATE_TEST_CASE_P(
+INSTANTIATE_TEST_SUITE_P(
ObjectStore,
StoreTestSpecificAUSize,
::testing::Values(
"memstore",
"filestore",
-#if defined(HAVE_LIBAIO)
+#if defined(WITH_BLUESTORE)
"bluestore",
#endif
"kstore"));
-#else
-
-// Google Test may not support value-parameterized tests with some
-// compilers. If we use conditional compilation to compile out all
-// code referring to the gtest_main library, MSVC linker will not link
-// that library at all and consequently complain about missing entry
-// point defined in that library (fatal error LNK1561: entry point
-// must be defined). This dummy test keeps gtest_main linked in.
-TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
-
-#endif
-
void doMany4KWritesTest(boost::scoped_ptr<ObjectStore>& store,
unsigned max_objects,
unsigned max_ops,
unsigned max_object_size,
unsigned max_write_size,
- unsigned write_alignment,
- store_statfs_t* res_stat)
+ unsigned write_alignment)
{
- ObjectStore::Sequencer osr("test");
MixedGenerator gen(555);
gen_type rng(time(NULL));
coll_t cid(spg_t(pg_t(0,555), shard_id_t::NO_SHARD));
+ store_statfs_t res_stat;
SyntheticWorkloadState test_obj(store.get(),
&gen,
&rng,
- &osr,
cid,
max_object_size,
max_write_size,
test_obj.write();
}
test_obj.wait_for_done();
- if (res_stat) {
- test_obj.statfs(*res_stat);
+ test_obj.statfs(res_stat);
+ if (!(res_stat.data_stored <= max_object_size) ||
+ !(res_stat.allocated <= max_object_size)) {
+ // this will provide more insight on the mismatch and
+ // helps to avoid any races during stats collection
+ test_obj.fsck(false);
+ // retrieving stats once again and assert if still broken
+ test_obj.statfs(res_stat);
+ ASSERT_LE(res_stat.data_stored, max_object_size);
+ ASSERT_LE(res_stat.allocated, max_object_size);
}
test_obj.shutdown();
}
StartDeferred(0x10000);
- store_statfs_t res_stat;
- unsigned max_object = 4*1024*1024;
-
- doMany4KWritesTest(store, 1, 1000, 4*1024*1024, 4*1024, 0, &res_stat);
-
- ASSERT_LE(res_stat.stored, max_object);
- ASSERT_EQ(res_stat.allocated, max_object);
+ const unsigned max_object = 4*1024*1024;
+ doMany4KWritesTest(store, 1, 1000, max_object, 4*1024, 0);
}
TEST_P(StoreTestSpecificAUSize, Many4KWritesNoCSumTest) {
if (string(GetParam()) != "bluestore")
return;
StartDeferred(0x10000);
- g_conf->set_val("bluestore_csum_type", "none");
- g_ceph_context->_conf->apply_changes(NULL);
- store_statfs_t res_stat;
- unsigned max_object = 4*1024*1024;
+ SetVal(g_conf(), "bluestore_csum_type", "none");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ const unsigned max_object = 4*1024*1024;
- doMany4KWritesTest(store, 1, 1000, max_object, 4*1024, 0, &res_stat );
-
- ASSERT_LE(res_stat.stored, max_object);
- ASSERT_EQ(res_stat.allocated, max_object);
- g_conf->set_val("bluestore_csum_type", "crc32c");
+ doMany4KWritesTest(store, 1, 1000, max_object, 4*1024, 0 );
}
TEST_P(StoreTestSpecificAUSize, TooManyBlobsTest) {
if (string(GetParam()) != "bluestore")
return;
StartDeferred(0x10000);
- store_statfs_t res_stat;
- unsigned max_object = 4*1024*1024;
- doMany4KWritesTest(store, 1, 1000, max_object, 4*1024, 0, &res_stat);
- ASSERT_LE(res_stat.stored, max_object);
- ASSERT_EQ(res_stat.allocated, max_object);
+ const unsigned max_object = 4*1024*1024;
+ doMany4KWritesTest(store, 1, 1000, max_object, 4*1024, 0);
}
-#if defined(HAVE_LIBAIO)
+#if defined(WITH_BLUESTORE)
void get_mempool_stats(uint64_t* total_bytes, uint64_t* total_items)
{
+ uint64_t meta_allocated = mempool::bluestore_cache_meta::allocated_bytes();
uint64_t onode_allocated = mempool::bluestore_cache_onode::allocated_bytes();
uint64_t other_allocated = mempool::bluestore_cache_other::allocated_bytes();
+ uint64_t meta_items = mempool::bluestore_cache_meta::allocated_items();
uint64_t onode_items = mempool::bluestore_cache_onode::allocated_items();
uint64_t other_items = mempool::bluestore_cache_other::allocated_items();
- cout << "onode(" << onode_allocated << "/" << onode_items
+ cout << "meta(" << meta_allocated << "/" << meta_items
+ << ") onode(" << onode_allocated << "/" << onode_items
<< ") other(" << other_allocated << "/" << other_items
<< ")" << std::endl;
- *total_bytes = onode_allocated + other_allocated;
+ *total_bytes = meta_allocated + onode_allocated + other_allocated;
*total_items = onode_items;
}
size_t block_size = 4096;
StartDeferred(block_size);
- g_conf->set_val("bluestore_compression_mode", "none");
- g_conf->set_val("bluestore_csum_type", "none");
- g_conf->set_val("bluestore_cache_size_hdd", "400000000");
- g_conf->set_val("bluestore_cache_size_ssd", "400000000");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_compression_mode", "none");
+ SetVal(g_conf(), "bluestore_csum_type", "none");
+ SetVal(g_conf(), "bluestore_cache_size_hdd", "400000000");
+ SetVal(g_conf(), "bluestore_cache_size_ssd", "400000000");
+ g_conf().apply_changes(nullptr);
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
get_mempool_stats(&total_bytes, &total_onodes);
ASSERT_EQ(total_onodes, 0u);
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(obj_size, 'a'));
t.write(cid, hoid, 0, bl.length(), bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
get_mempool_stats(&total_bytes, &total_onodes);
{
ObjectStore::Transaction t;
t.truncate(cid, hoid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
for( size_t j = 0; j < obj_size; j+= bl.length()) {
ObjectStore::Transaction t;
t.write(cid, hoid, j, bl.length(), bl);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
get_mempool_stats(&total_bytes2, &total_onodes);
{
bufferlist bl;
for (size_t i = 0; i < obj_size; i += 0x1000) {
- store->read(cid, hoid, i, 0x1000, bl);
+ store->read(ch, hoid, i, 0x1000, bl);
}
}
get_mempool_stats(&total_bytes, &total_onodes);
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_ceph_context->_conf->set_val("bluestore_cache_size_hdd", "4000000");
- g_ceph_context->_conf->set_val("bluestore_cache_size_ssd", "4000000");
- g_conf->set_val("bluestore_compression_mode", "none");
- g_conf->set_val("bluestore_csum_type", "crc32c");
-
}
TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwrite) {
size_t block_size = 4096;
StartDeferred(block_size);
- g_conf->set_val("bluestore_max_blob_size", "65536");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_max_blob_size", "65536");
+ g_conf().apply_changes(nullptr);
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
const PerfCounters* logger = store->get_perf_counters();
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(block_size * 2, 'a'));
t.write(cid, hoid, 0, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(block_size, 'b'));
t.write(cid, hoid, 0, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(block_size * 2, 'c'));
t.write(cid, hoid, block_size * 2, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(block_size * 2, 'd'));
t.write(cid, hoid, block_size * 5, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, 0, block_size, bl);
+ r = store->read(ch, hoid, 0, block_size, bl);
ASSERT_EQ(r, (int)block_size);
expected.append(string(block_size, 'b'));
ASSERT_TRUE(bl_eq(expected, bl));
// Currently we are unable to reuse blob when overwriting in a single step
t.write(cid, hoid, block_size * 6, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, 0, block_size, bl);
+ r = store->read(ch, hoid, 0, block_size, bl);
ASSERT_EQ(r, (int)block_size);
expected.append(string(block_size, 'b'));
ASSERT_TRUE(bl_eq(expected, bl));
bl.append(std::string(block_size, 'f'));
t.write(cid, hoid, block_size * 4, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, 0, block_size, bl);
+ r = store->read(ch, hoid, 0, block_size, bl);
ASSERT_EQ(r, (int)block_size);
expected.append(string(block_size, 'b'));
ASSERT_TRUE(bl_eq(expected, bl));
bl.clear();
expected.clear();
- r = store->read(cid, hoid, block_size, block_size, bl);
+ r = store->read(ch, hoid, block_size, block_size, bl);
ASSERT_EQ(r, (int)block_size);
expected.append(string(block_size, 'a'));
ASSERT_TRUE(bl_eq(expected, bl));
bl.clear();
expected.clear();
- r = store->read(cid, hoid, block_size * 2, block_size * 2, bl);
+ r = store->read(ch, hoid, block_size * 2, block_size * 2, bl);
ASSERT_EQ(r, (int)block_size * 2);
expected.append(string(block_size * 2, 'c'));
ASSERT_TRUE(bl_eq(expected, bl));
bl.clear();
expected.clear();
- r = store->read(cid, hoid, block_size * 4, block_size, bl);
+ r = store->read(ch, hoid, block_size * 4, block_size, bl);
ASSERT_EQ(r, (int)block_size);
expected.append(string(block_size, 'f'));
ASSERT_TRUE(bl_eq(expected, bl));
bl.clear();
expected.clear();
- r = store->read(cid, hoid, block_size * 5, block_size, bl);
+ r = store->read(ch, hoid, block_size * 5, block_size, bl);
ASSERT_EQ(r, (int)block_size);
expected.append(string(block_size, 'd'));
ASSERT_TRUE(bl_eq(expected, bl));
bl.clear();
expected.clear();
- r = store->read(cid, hoid, block_size * 5, block_size * 3, bl);
+ r = store->read(ch, hoid, block_size * 5, block_size * 3, bl);
ASSERT_EQ(r, (int)block_size * 3);
expected.append(string(block_size, 'd'));
expected.append(string(block_size * 2, 'e'));
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_conf->set_val("bluestore_max_blob_size", "0");
-
}
TEST_P(StoreTestSpecificAUSize, BlobReuseOnOverwriteReverse) {
size_t block_size = 4096;
StartDeferred(block_size);
- g_conf->set_val("bluestore_max_blob_size", "65536");
+ SetVal(g_conf(), "bluestore_max_blob_size", "65536");
+ g_conf().apply_changes(nullptr);
- g_conf->apply_changes(NULL);
-
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
+ auto ch = store->create_new_collection(cid);
+
const PerfCounters* logger = store->get_perf_counters();
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(block_size * 2, 'a'));
t.write(cid, hoid, block_size * 10, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(block_size, 'b'));
t.write(cid, hoid, block_size * 9, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, block_size * 9, block_size * 2, bl);
+ r = store->read(ch, hoid, block_size * 9, block_size * 2, bl);
ASSERT_EQ(r, (int)block_size * 2);
expected.append(string(block_size, 'b'));
expected.append(string(block_size, 'a'));
bl.append(std::string(block_size, 'c'));
t.write(cid, hoid, block_size * 7, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, block_size * 7, block_size * 3, bl);
+ r = store->read(ch, hoid, block_size * 7, block_size * 3, bl);
ASSERT_EQ(r, (int)block_size * 3);
expected.append(string(block_size, 'c'));
expected.append(string(block_size, 0));
bl.append(std::string(block_size, 'd'));
t.write(cid, hoid, block_size * 13, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, block_size * 11, block_size * 3, bl);
+ r = store->read(ch, hoid, block_size * 11, block_size * 3, bl);
ASSERT_EQ(r, (int)block_size * 3);
expected.append(string(block_size, 'a'));
expected.append(string(block_size, 0));
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
t.write(cid, hoid, block_size * 19, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, block_size * 17, block_size * 3, bl);
+ r = store->read(ch, hoid, block_size * 17, block_size * 3, bl);
ASSERT_EQ(r, (int)block_size * 3);
expected.append(string(block_size, 'e'));
expected.append(string(block_size, 0));
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
t.write(cid, hoid, block_size * 18, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, block_size * 16, block_size * 4, bl);
+ r = store->read(ch, hoid, block_size * 16, block_size * 4, bl);
ASSERT_EQ(r, (int)block_size * 4);
expected.append(string(block_size, 'f'));
expected.append(string(block_size, 'e'));
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_conf->set_val("bluestore_max_blob_size", "0");
}
TEST_P(StoreTestSpecificAUSize, BlobReuseOnSmallOverwrite) {
size_t block_size = 4096;
StartDeferred(block_size);
- g_conf->set_val("bluestore_max_blob_size", "65536");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_max_blob_size", "65536");
+ g_conf().apply_changes(nullptr);
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid(hobject_t("test_hint", "", CEPH_NOSNAP, 0, -1, ""));
const PerfCounters* logger = store->get_perf_counters();
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
t.write(cid, hoid, 0, bl.length(), bl, CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
t.write(cid, hoid, block_size * 2, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(3, 'b'));
t.write(cid, hoid, block_size + 1, bl.length(), bl,
CEPH_OSD_OP_FLAG_FADVISE_WILLNEED);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
// thread to update stats.
sleep(1);
bufferlist bl, expected;
- r = store->read(cid, hoid, 0, block_size * 3, bl);
+ r = store->read(ch, hoid, 0, block_size * 3, bl);
ASSERT_EQ(r, (int)block_size * 3);
expected.append(string(block_size, 'a'));
expected.append(string(1, 0));
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_conf->set_val("bluestore_max_blob_size", "0");
}
// The test case to reproduce an issue when write happens
size_t block_size = 0x10000;
StartDeferred(block_size);
- g_conf->set_val("bluestore_csum_type", "xxhash64");
- g_conf->set_val("bluestore_max_target_blob", "524288"); // for sure
+ SetVal(g_conf(), "bluestore_csum_type", "xxhash64");
+ SetVal(g_conf(), "bluestore_max_blob_size", "524288"); // for sure
- g_conf->apply_changes(NULL);
+ g_conf().apply_changes(nullptr);
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
ghobject_t hoid1(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
bl.append(std::string(0x80000, 'a'));
t.write(cid, hoid1, 0, bl.length(), bl, 0);
t.zero(cid, hoid1, 0x719e0, 0x75b0 );
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
bl2.append(std::string(0x70000, 'b'));
t.write(cid, hoid1, 0, bl2.length(), bl2, 0);
t.zero(cid, hoid1, 0, 0x50000);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
+ ch.reset();
store->umount();
store->mount();
+ ch = store->open_collection(cid);
{
// do a write to zero space in between some extents sharing the same blob
bl.append(std::string(0x6520, 'c'));
t.write(cid, hoid1, 0x71c00, bl.length(), bl, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
ObjectStore::Transaction t;
bufferlist bl, expected;
- r = store->read(cid, hoid1, 0x70000, 0x9c00, bl);
+ r = store->read(ch, hoid1, 0x70000, 0x9c00, bl);
ASSERT_EQ(r, (int)0x9c00);
expected.append(string(0x19e0, 'a'));
expected.append(string(0x220, 0));
t.remove(cid, hoid1);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
- g_conf->set_val("bluestore_max_target_blob", "524288");
- g_conf->set_val("bluestore_csum_type", "crc32c");
}
-#endif //#if defined(HAVE_LIBAIO)
+#endif //#if defined(WITH_BLUESTORE)
TEST_P(StoreTest, KVDBHistogramTest) {
if (string(GetParam()) != "bluestore")
return;
- ObjectStore::Sequencer osr("test");
int NUM_OBJS = 200;
int r = 0;
coll_t cid;
bufferptr ap(0x1000);
memset(ap.c_str(), 'a', 0x1000);
a.append(ap);
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
for (int i = 0; i < NUM_OBJS; ++i) {
snprintf(buf, sizeof(buf), "%d", i);
ghobject_t hoid(hobject_t(sobject_t(base + string(buf), CEPH_NOSNAP)));
t.write(cid, hoid, 0, 0x1000, a);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
if (string(GetParam()) != "bluestore")
return;
- g_conf->set_val("rocksdb_perf", "true");
- g_conf->set_val("rocksdb_collect_compaction_stats", "true");
- g_conf->set_val("rocksdb_collect_extended_stats","true");
- g_conf->set_val("rocksdb_collect_memory_stats","true");
- g_ceph_context->_conf->apply_changes(NULL);
+ SetVal(g_conf(), "rocksdb_perf", "true");
+ SetVal(g_conf(), "rocksdb_collect_compaction_stats", "true");
+ SetVal(g_conf(), "rocksdb_collect_extended_stats","true");
+ SetVal(g_conf(), "rocksdb_collect_memory_stats","true");
+ g_ceph_context->_conf.apply_changes(nullptr);
int r = store->umount();
ASSERT_EQ(r, 0);
r = store->mount(); //to force rocksdb stats
ASSERT_EQ(r, 0);
- ObjectStore::Sequencer osr("test");
int NUM_OBJS = 200;
coll_t cid;
string base("testobj.");
bufferptr ap(0x1000);
memset(ap.c_str(), 'a', 0x1000);
a.append(ap);
+ auto ch = store->create_new_collection(cid);
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
for (int i = 0; i < NUM_OBJS; ++i) {
snprintf(buf, sizeof(buf), "%d", i);
ghobject_t hoid(hobject_t(sobject_t(base + string(buf), CEPH_NOSNAP)));
t.write(cid, hoid, 0, 0x1000, a);
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
store->get_db_statistics(f);
f->flush(cout);
cout << std::endl;
- g_conf->set_val("rocksdb_perf", "false");
- g_conf->set_val("rocksdb_collect_compaction_stats", "false");
- g_conf->set_val("rocksdb_collect_extended_stats","false");
- g_conf->set_val("rocksdb_collect_memory_stats","false");
}
-#if defined(HAVE_LIBAIO)
+#if defined(WITH_BLUESTORE)
TEST_P(StoreTestSpecificAUSize, garbageCollection) {
- ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
int buf_len = 256 * 1024;
} else {\
t.write(cid, hoid, offset, bl.length(), bl);\
}\
- r = apply_transaction(store, &osr, std::move(t));\
+ r = queue_transaction(store, ch, std::move(t));\
ASSERT_EQ(r, 0);\
}
StartDeferred(65536);
- g_conf->set_val("bluestore_compression_max_blob_size", "524288");
- g_conf->set_val("bluestore_compression_min_blob_size", "262144");
- g_conf->set_val("bluestore_compression_mode", "force");
- g_conf->apply_changes(NULL);
+ SetVal(g_conf(), "bluestore_compression_max_blob_size", "524288");
+ SetVal(g_conf(), "bluestore_compression_min_blob_size", "262144");
+ SetVal(g_conf(), "bluestore_max_blob_size", "524288");
+ SetVal(g_conf(), "bluestore_compression_mode", "force");
+ g_conf().apply_changes(nullptr);
+
+ auto ch = store->create_new_collection(cid);
ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
{
bufferlist in;
- r = store->read(cid, hoid, 0, 5, in);
+ r = store->read(ch, hoid, 0, 5, in);
ASSERT_EQ(-ENOENT, r);
}
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
{
{
- bool exists = store->exists(cid, hoid);
+ bool exists = store->exists(ch, hoid);
ASSERT_TRUE(!exists);
ObjectStore::Transaction t;
t.touch(cid, hoid);
cerr << "Creating object " << hoid << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
- exists = store->exists(cid, hoid);
+ exists = store->exists(ch, hoid);
ASSERT_EQ(true, exists);
}
bufferlist bl;
WRITE_AT(0, buf_len);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
}
{
struct store_statfs_t statfs;
WRITE_AT(write_offset - 2 * overlap_offset, buf_len);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x20000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x20000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0u);
}
WRITE_AT(write_offset - overlap_offset, buf_len);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x20000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x20000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x10000u);
}
WRITE_AT(write_offset - 3 * overlap_offset, buf_len);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x20000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x20000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x20000u);
}
WRITE_AT(write_offset + 1, overlap_offset-1);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x20000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x20000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x20000u);
}
WRITE_AT(write_offset + 1, overlap_offset);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x3ffffu);
}
WRITE_AT(0, buf_len-1);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x40001u);
}
- g_conf->set_val("bluestore_gc_enable_total_threshold", "1"); //forbid GC when saving = 0
+ SetVal(g_conf(), "bluestore_gc_enable_total_threshold", "1"); //forbid GC when saving = 0
{
struct store_statfs_t statfs;
WRITE_AT(1, overlap_offset-2);
WRITE_AT(overlap_offset * 2 + 1, overlap_offset-2);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x10000);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x10000);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x40001u);
}
WRITE_AT(overlap_offset + 1, overlap_offset-2);
int r = store->statfs(&statfs);
ASSERT_EQ(r, 0);
- ASSERT_EQ(statfs.compressed_allocated, 0x0);
+ ASSERT_EQ(statfs.data_compressed_allocated, 0x0);
const PerfCounters* counters = store->get_perf_counters();
ASSERT_EQ(counters->get(l_bluestore_gc_merged), 0x40007u);
}
ObjectStore::Transaction t;
t.remove(cid, hoid);
cerr << "Cleaning" << std::endl;
- r = apply_transaction(store, &osr, std::move(t));
+ r = queue_transaction(store, ch, std::move(t));
ASSERT_EQ(r, 0);
}
}
- g_conf->set_val("bluestore_gc_enable_total_threshold", "0");
- g_conf->set_val("bluestore_compression_min_blob_size", "0");
- g_conf->set_val("bluestore_compression_max_blob_size", "0");
- g_conf->set_val("bluestore_compression_mode", "none");
- g_conf->apply_changes(NULL);
}
-#endif
+
+TEST_P(StoreTestSpecificAUSize, fsckOnUnalignedDevice) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_size",
+ stringify(0x280005000).c_str()); //10 Gb + 4K
+ SetVal(g_conf(), "bluestore_fsck_on_mount", "false");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "false");
+ StartDeferred(0x4000);
+ store->umount();
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
+ store->mount();
+
+}
+
+TEST_P(StoreTestSpecificAUSize, fsckOnUnalignedDevice2) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_size",
+ stringify(0x280005000).c_str()); //10 Gb + 20K
+ SetVal(g_conf(), "bluestore_fsck_on_mount", "false");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "false");
+ StartDeferred(0x1000);
+ store->umount();
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
+ store->mount();
+}
+
+namespace {
+ ghobject_t make_object(const char* name, int64_t pool) {
+ sobject_t soid{name, CEPH_NOSNAP};
+ uint32_t hash = std::hash<sobject_t>{}(soid);
+ return ghobject_t{hobject_t{soid, "", hash, pool, ""}};
+ }
+}
+
+TEST_P(StoreTestSpecificAUSize, BluestoreRepairTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+ const size_t offs_base = 65536 / 2;
+
+ SetVal(g_conf(), "bluestore_fsck_on_mount", "false");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "false");
+ SetVal(g_conf(), "bluestore_max_blob_size",
+ stringify(2 * offs_base).c_str());
+ SetVal(g_conf(), "bluestore_extent_map_shard_max_size", "12000");
+ SetVal(g_conf(), "bluestore_fsck_error_on_no_per_pool_stats", "false");
+
+ StartDeferred(0x10000);
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (store.get());
+
+ // 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();
+ //////////// leaked pextent fix ////////////
+ cerr << "fix leaked pextents" << std::endl;
+ ASSERT_EQ(bstore->fsck(false), 0);
+ ASSERT_EQ(bstore->repair(false), 0);
+ bstore->mount();
+ bstore->inject_leaked(0x30000);
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 1);
+ ASSERT_EQ(bstore->repair(false), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+
+ //////////// false free fix ////////////
+ cerr << "fix false free pextents" << std::endl;
+ bstore->mount();
+ bstore->inject_false_free(cid, hoid);
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 2);
+ ASSERT_EQ(bstore->repair(false), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+
+ //////////// verify invalid statfs ///////////
+ cerr << "fix invalid statfs" << std::endl;
+ store_statfs_t statfs0, statfs;
+ bstore->mount();
+ ASSERT_EQ(bstore->statfs(&statfs0), 0);
+ statfs = statfs0;
+ statfs.allocated += 0x10000;
+ statfs.data_stored += 0x10000;
+ ASSERT_FALSE(statfs0 == statfs);
+ bstore->inject_statfs("bluestore_statfs", statfs);
+ bstore->umount();
+
+ ASSERT_EQ(bstore->fsck(false), 2);
+ ASSERT_EQ(bstore->repair(false), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+ ASSERT_EQ(bstore->mount(), 0);
+ ASSERT_EQ(bstore->statfs(&statfs), 0);
+ // adjust free space to success in comparison
+ statfs0.available = statfs.available;
+ ASSERT_EQ(statfs0, statfs);
+
+ ///////// undecodable shared blob key / stray shared blob records ///////
+ cerr << "undecodable shared blob key" << std::endl;
+ bstore->inject_broken_shared_blob_key("undec1",
+ bufferlist());
+ bstore->inject_broken_shared_blob_key("undecodable key 2",
+ bufferlist());
+ bstore->inject_broken_shared_blob_key("undecodable key 3",
+ bufferlist());
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 3);
+ ASSERT_EQ(bstore->repair(false), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+
+ cerr << "misreferencing" << std::endl;
+ bstore->mount();
+ bstore->inject_misreference(cid, hoid, cid, hoid_dup, 0);
+ bstore->inject_misreference(cid, hoid, cid, hoid_dup, (offs_base * repeats) / 2);
+ bstore->inject_misreference(cid, hoid, cid, hoid_dup, offs_base * (repeats -1) );
+
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 6);
+ ASSERT_EQ(bstore->repair(false), 0);
+
+ ASSERT_EQ(bstore->fsck(true), 0);
+
+ // reproducing issues #21040 & 20983
+ SetVal(g_conf(), "bluestore_debug_inject_bug21040", "true");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ bstore->mount();
+
+ cerr << "repro bug #21040" << std::endl;
+ {
+ auto ch = store->open_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ bl.append("0123456789012345");
+ t.write(cid, hoid3, offs_base, bl.length(), bl);
+ bl.clear();
+ bl.append('!');
+ t.write(cid, hoid3, 0, bl.length(), bl);
+
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ t.clone(cid, hoid3, hoid3_cloned);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 3);
+ ASSERT_LE(bstore->repair(false), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+ }
+
+ cerr << "Zombie spanning blob" << std::endl;
+ {
+ bstore->mount();
+ ghobject_t hoid4 = make_object("Object 4", pool);
+ auto ch = store->open_collection(cid);
+ {
+ bufferlist bl;
+ string s(0x1000, 'a');
+ bl.append(s);
+ ObjectStore::Transaction t;
+ for(size_t i = 0; i < 0x10; i++) {
+ t.write(cid, hoid4, i * bl.length(), bl.length(), bl);
+ }
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ sleep(5);
+ {
+ bstore->inject_zombie_spanning_blob(cid, hoid4, 12345);
+ bstore->inject_zombie_spanning_blob(cid, hoid4, 23456);
+ bstore->inject_zombie_spanning_blob(cid, hoid4, 23457);
+ }
+
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), 1);
+ ASSERT_LE(bstore->repair(false), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+ }
+
+ cerr << "Completing" << std::endl;
+ bstore->mount();
+
+}
+
+TEST_P(StoreTestSpecificAUSize, BluestoreBrokenZombieRepairTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_fsck_on_mount", "false");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "false");
+
+ StartDeferred(0x10000);
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (store.get());
+
+ int r;
+
+ cerr << "initializing" << std::endl;
+ {
+ const size_t col_count = 16;
+ const size_t obj_count = 1024;
+ ObjectStore::CollectionHandle ch[col_count];
+ ghobject_t hoid[col_count][obj_count];
+
+ unique_ptr<coll_t> cid[col_count];
+
+ for (size_t i = 0; i < col_count; i++) {
+ cid[i].reset(new coll_t(spg_t(pg_t(0, i), shard_id_t::NO_SHARD)));
+ ch[i] = store->create_new_collection(*cid[i]);
+ for (size_t j = 0; j < obj_count; j++) {
+ hoid[i][j] = make_object(stringify(j).c_str(), i);
+ }
+ }
+
+ for (size_t i = 0; i < col_count; i++) {
+ ObjectStore::Transaction t;
+ t.create_collection(*cid[i], 0);
+ r = queue_transaction(store, ch[i], std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ cerr << "onode preparing" << std::endl;
+ bufferlist bl;
+ string s(0x1000, 'a');
+ bl.append(s);
+
+ for (size_t i = 0; i < col_count; i++) {
+ for (size_t j = 0; j < obj_count; j++) {
+ ObjectStore::Transaction t;
+ t.write(*cid[i], hoid[i][j], bl.length(), bl.length(), bl);
+ r = queue_transaction(store, ch[i], std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ }
+ cerr << "Zombie spanning blob injection" << std::endl;
+
+ sleep(5);
+
+ for (size_t i = 0; i < col_count; i++) {
+ for (size_t j = 0; j < obj_count; j++) {
+ bstore->inject_zombie_spanning_blob(*cid[i], hoid[i][j], 12345);
+ }
+ }
+
+ cerr << "fscking/fixing" << std::endl;
+ bstore->umount();
+ ASSERT_EQ(bstore->fsck(false), col_count * obj_count);
+ ASSERT_LE(bstore->quick_fix(), 0);
+ ASSERT_EQ(bstore->fsck(false), 0);
+ }
+
+ cerr << "Completing" << std::endl;
+ bstore->mount();
+}
+
+TEST_P(StoreTest, BluestoreRepairGlobalStats) {
+ if (string(GetParam()) != "bluestore")
+ return;
+ const size_t offs_base = 65536 / 2;
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (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<BlueStore*> (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;
+
+ SetVal(g_conf(), "rocksdb_perf", "true");
+ SetVal(g_conf(), "rocksdb_collect_compaction_stats", "true");
+ SetVal(g_conf(), "rocksdb_collect_extended_stats","true");
+ SetVal(g_conf(), "rocksdb_collect_memory_stats","true");
+
+ // disable cache
+ SetVal(g_conf(), "bluestore_cache_size_ssd", "0");
+ SetVal(g_conf(), "bluestore_cache_size_hdd", "0");
+ SetVal(g_conf(), "bluestore_cache_size", "0");
+ g_ceph_context->_conf.apply_changes(nullptr);
+
+ int r = store->umount();
+ ASSERT_EQ(r, 0);
+ r = store->mount();
+ ASSERT_EQ(r, 0);
+
+ BlueStore* bstore = NULL;
+ EXPECT_NO_THROW(bstore = dynamic_cast<BlueStore*> (store.get()));
+
+ coll_t cid;
+ ghobject_t hoid(hobject_t("test_db_statistics", "", CEPH_NOSNAP, 0, 0, ""));
+ auto ch = bstore->create_new_collection(cid);
+ bufferlist bl;
+ bl.append("0123456789abcdefghi");
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ t.touch(cid, hoid);
+ t.write(cid, hoid, 0, bl.length(), bl);
+ cerr << "Write object" << std::endl;
+ r = queue_transaction(bstore, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ bufferlist readback;
+ r = store->read(ch, hoid, 0, bl.length(), readback);
+ ASSERT_EQ(static_cast<int>(bl.length()), r);
+ ASSERT_TRUE(bl_eq(bl, readback));
+ }
+ Formatter *f = Formatter::create("store_test", "json-pretty", "json-pretty");
+ EXPECT_NO_THROW(store->get_db_statistics(f));
+ f->flush(cout);
+ cout << std::endl;
+}
+
+TEST_P(StoreTest, BluestorePerPoolOmapFixOnMount)
+{
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (store.get());
+ const uint64_t pool = 555;
+ coll_t cid(spg_t(pg_t(0, pool), shard_id_t::NO_SHARD));
+ ghobject_t oid = make_object("Object 1", pool);
+ ghobject_t oid2 = make_object("Object 2", pool);
+ // fill the store with some data
+ auto ch = store->create_new_collection(cid);
+ map<string, bufferlist> omap;
+ bufferlist h;
+ h.append("header");
+ {
+ omap["omap_key"].append("omap value");
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ t.touch(cid, oid);
+ t.omap_setheader(cid, oid, h);
+ t.touch(cid, oid2);
+ t.omap_setheader(cid, oid2, h);
+ int r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+
+ // inject legacy omaps
+ bstore->inject_legacy_omap();
+ bstore->inject_legacy_omap(cid, oid);
+ bstore->inject_legacy_omap(cid, oid2);
+
+ bstore->umount();
+
+ // check we injected an issue
+ SetVal(g_conf(), "bluestore_fsck_quick_fix_on_mount", "false");
+ SetVal(g_conf(), "bluestore_fsck_error_on_no_per_pool_omap", "true");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ ASSERT_EQ(bstore->fsck(false), 3);
+
+ // set autofix and mount
+ SetVal(g_conf(), "bluestore_fsck_quick_fix_on_mount", "true");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ bstore->mount();
+ bstore->umount();
+
+ // check we fixed it..
+ ASSERT_EQ(bstore->fsck(false), 0);
+ bstore->mount();
+
+ //
+ // Now repro https://tracker.ceph.com/issues/43824
+ //
+ // inject legacy omaps again
+ bstore->inject_legacy_omap();
+ bstore->inject_legacy_omap(cid, oid);
+ bstore->inject_legacy_omap(cid, oid2);
+ bstore->umount();
+
+ // check we injected an issue
+ SetVal(g_conf(), "bluestore_fsck_quick_fix_on_mount", "true");
+ SetVal(g_conf(), "bluestore_fsck_error_on_no_per_pool_omap", "true");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ bstore->mount();
+ ch = store->open_collection(cid);
+
+ {
+ // write to onode which will partiall revert per-pool
+ // omap repair done on mount due to #43824.
+ // And object removal will leave stray per-pool omap recs
+ //
+ ObjectStore::Transaction t;
+ bufferlist bl;
+ bl.append("data");
+ //this triggers onode rec update and hence legacy omap
+ t.write(cid, oid, 0, bl.length(), bl);
+ t.remove(cid, oid2); // this will trigger stray per-pool omap
+ int r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ bstore->umount();
+ // check omap's been fixed.
+ ASSERT_EQ(bstore->fsck(false), 0); // this will fail without fix for #43824
+
+ bstore->mount();
+}
+
+TEST_P(StoreTestSpecificAUSize, BluestoreTinyDevFailure) {
+ if (string(GetParam()) != "bluestore")
+ return;
+ // This caused superblock overwrite by bluefs, see
+ // https://tracker.ceph.com/issues/24480
+ SetVal(g_conf(), "bluestore_block_size",
+ stringify(1024 * 1024 * 1024).c_str()); //1 Gb
+ SetVal(g_conf(), "bluestore_block_db_size", "0");
+ SetVal(g_conf(), "bluestore_block_db_create", "false");
+ SetVal(g_conf(), "bluestore_bluefs_min",
+ stringify(1024 * 1024 * 1024).c_str());
+ StartDeferred(0x1000);
+ store->umount();
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
+ store->mount();
+}
+
+TEST_P(StoreTestSpecificAUSize, BluestoreTinyDevFailure2) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ // This caused assert in allocator as initial bluefs extent as slow device
+ // overlaped with superblock
+ // https://tracker.ceph.com/issues/24480
+ SetVal(g_conf(), "bluestore_block_size",
+ stringify(1024 * 1024 * 1024).c_str()); //1 Gb
+ SetVal(g_conf(), "bluestore_block_db_size",
+ stringify(1024 * 1024 * 1024).c_str()); //1 Gb
+ SetVal(g_conf(), "bluestore_block_db_create", "true");
+ SetVal(g_conf(), "bluestore_bluefs_min",
+ stringify(1024 * 1024 * 1024).c_str());
+ StartDeferred(0x1000);
+ store->umount();
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
+ store->mount();
+}
+
+TEST_P(StoreTest, SpuriousReadErrorTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ int r;
+ auto logger = store->get_perf_counters();
+ coll_t cid;
+ auto ch = store->create_new_collection(cid);
+ ghobject_t hoid(hobject_t(sobject_t("foo", CEPH_NOSNAP)));
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ cerr << "Creating collection " << cid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ bufferlist test_data;
+ bufferptr ap(0x2000);
+ memset(ap.c_str(), 'a', 0x2000);
+ test_data.append(ap);
+ {
+ ObjectStore::Transaction t;
+ t.write(cid, hoid, 0, 0x2000, test_data);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ // force cache clear
+ EXPECT_EQ(store->umount(), 0);
+ EXPECT_EQ(store->mount(), 0);
+ }
+ ch = store->open_collection(cid);
+
+ cerr << "Injecting CRC error with no retry, expecting EIO" << std::endl;
+ SetVal(g_conf(), "bluestore_retry_disk_reads", "0");
+ SetVal(g_conf(), "bluestore_debug_inject_csum_err_probability", "1");
+ g_ceph_context->_conf.apply_changes(nullptr);
+ {
+ bufferlist in;
+ r = store->read(ch, hoid, 0, 0x2000, in, CEPH_OSD_OP_FLAG_FADVISE_NOCACHE);
+ ASSERT_EQ(-EIO, r);
+ ASSERT_EQ(logger->get(l_bluestore_read_eio), 1u);
+ ASSERT_EQ(logger->get(l_bluestore_reads_with_retries), 0u);
+ }
+
+ cerr << "Injecting CRC error with retries, expecting success after several retries" << std::endl;
+ SetVal(g_conf(), "bluestore_retry_disk_reads", "255");
+ SetVal(g_conf(), "bluestore_debug_inject_csum_err_probability", "0.8");
+ /**
+ * Probabilistic test: 25 reads, each has a 80% chance of failing with 255 retries
+ * Probability of at least one retried read: 1 - (0.2 ** 25) = 100% - 3e-18
+ * Probability of a random test failure: 1 - ((1 - (0.8 ** 255)) ** 25) ~= 5e-24
+ */
+ g_ceph_context->_conf.apply_changes(nullptr);
+ {
+ for (int i = 0; i < 25; ++i) {
+ bufferlist in;
+ r = store->read(ch, hoid, 0, 0x2000, in, CEPH_OSD_OP_FLAG_FADVISE_NOCACHE);
+ ASSERT_EQ(0x2000, r);
+ ASSERT_TRUE(bl_eq(test_data, in));
+ }
+ ASSERT_GE(logger->get(l_bluestore_reads_with_retries), 1u);
+ }
+}
+
+TEST_P(StoreTest, allocateBlueFSTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ BlueStore* bstore = NULL;
+ EXPECT_NO_THROW(bstore = dynamic_cast<BlueStore*> (store.get()));
+
+ struct store_statfs_t statfs;
+ store->statfs(&statfs);
+
+ uint64_t to_alloc = g_conf().get_val<Option::size_t>("bluefs_alloc_size");
+
+ int r = bstore->allocate_bluefs_freespace(to_alloc, to_alloc, nullptr);
+ ASSERT_EQ(r, 0);
+ r = bstore->allocate_bluefs_freespace(statfs.total, statfs.total, nullptr);
+ ASSERT_EQ(r, -ENOSPC);
+ r = bstore->allocate_bluefs_freespace(to_alloc * 16, to_alloc * 16, nullptr);
+ ASSERT_EQ(r, 0);
+ store->umount();
+ ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
+ r = store->mount();
+ ASSERT_EQ(r, 0);
+}
+
+TEST_P(StoreTest, mergeRegionTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_fsck_on_mount", "true");
+ SetVal(g_conf(), "bluestore_fsck_on_umount", "true");
+ SetVal(g_conf(), "bdev_debug_inflight_ios", "true");
+ g_ceph_context->_conf.apply_changes(nullptr);
+
+ uint32_t chunk_size = g_ceph_context->_conf->bdev_block_size;
+ int r = -1;
+ coll_t cid;
+ ghobject_t hoid(hobject_t(sobject_t("Object", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ t.touch(cid, hoid);
+ cerr << "Creating object " << hoid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ bufferlist bl5;
+ bl5.append("abcde");
+ uint64_t offset = 0;
+ { // 1. same region
+ ObjectStore::Transaction t;
+ t.write(cid, hoid, offset, 5, bl5);
+ t.write(cid, hoid, 0xa + offset, 5, bl5);
+ t.write(cid, hoid, 0x14 + offset, 5, bl5);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ { // 2. adjacent regions
+ ObjectStore::Transaction t;
+ offset = chunk_size;
+ t.write(cid, hoid, offset, 5, bl5);
+ t.write(cid, hoid, offset + chunk_size + 3, 5, bl5);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ { // 3. front merge
+ ObjectStore::Transaction t;
+ offset = chunk_size * 2;
+ t.write(cid, hoid, offset, 5, bl5);
+ t.write(cid, hoid, offset + chunk_size - 2, 5, bl5);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ { // 4. back merge
+ ObjectStore::Transaction t;
+ bufferlist blc2;
+ blc2.append_zero(chunk_size + 2);
+
+ offset = chunk_size * 3;
+ t.write(cid, hoid, offset, chunk_size + 2, blc2);
+ t.write(cid, hoid, offset + chunk_size + 3, 5, bl5);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ { // 5. overlapping
+ ObjectStore::Transaction t;
+ uint64_t final_len = 0;
+ offset = chunk_size * 10;
+ bufferlist bl2c2;
+ bl2c2.append_zero(chunk_size * 2);
+ t.write(cid, hoid, offset + chunk_size * 3 - 3, chunk_size * 2, bl2c2);
+ bl2c2.append_zero(2);
+ t.write(cid, hoid, offset + chunk_size - 2, chunk_size * 2 + 2, bl2c2);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ final_len = (offset + chunk_size * 3 - 3) + (chunk_size * 2);
+ bufferlist bl;
+ r = store->read(ch, hoid, 0, final_len, bl);
+ ASSERT_EQ(final_len, static_cast<uint64_t>(r));
+ }
+}
+
+TEST_P(StoreTestSpecificAUSize, BluestoreEnforceHWSettingsHdd) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_debug_enforce_settings", "hdd");
+ StartDeferred(0x1000);
+
+ int r;
+ coll_t cid;
+ ghobject_t hoid(hobject_t(sobject_t("Object", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ cerr << "Creating collection " << cid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ bufferlist bl, orig;
+ string s(g_ceph_context->_conf->bluestore_max_blob_size_hdd, '0');
+ bl.append(s);
+ t.write(cid, hoid, 0, bl.length(), bl);
+ cerr << "write" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ const PerfCounters* logger = store->get_perf_counters();
+ ASSERT_EQ(logger->get(l_bluestore_write_big_blobs), 1u);
+ }
+}
+
+TEST_P(StoreTestSpecificAUSize, BluestoreEnforceHWSettingsSsd) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_debug_enforce_settings", "ssd");
+ StartDeferred(0x1000);
+
+ int r;
+ coll_t cid;
+ ghobject_t hoid(hobject_t(sobject_t("Object", CEPH_NOSNAP)));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ cerr << "Creating collection " << cid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ bufferlist bl, orig;
+ string s(g_ceph_context->_conf->bluestore_max_blob_size_ssd * 8, '0');
+ bl.append(s);
+ t.write(cid, hoid, 0, bl.length(), bl);
+ cerr << "write" << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ const PerfCounters* logger = store->get_perf_counters();
+ ASSERT_EQ(logger->get(l_bluestore_write_big_blobs), 8u);
+ }
+}
+
+TEST_P(StoreTestSpecificAUSize, ReproNoBlobMultiTest) {
+
+ if(string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_db_create", "true");
+ SetVal(g_conf(), "bluestore_block_db_size", "4294967296");
+ SetVal(g_conf(), "bluestore_block_size", "12884901888");
+ SetVal(g_conf(), "bluestore_max_blob_size", "524288");
+
+ g_conf().apply_changes(nullptr);
+
+ StartDeferred(65536);
+
+ int r;
+ coll_t cid;
+ ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP)));
+ ghobject_t hoid2 = hoid;
+ hoid2.hobj.snap = 1;
+
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ cerr << "Creating collection " << cid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ bool exists = store->exists(ch, hoid);
+ ASSERT_TRUE(!exists);
+
+ ObjectStore::Transaction t;
+ t.touch(cid, hoid);
+ cerr << "Creating object " << hoid << std::endl;
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+
+ exists = store->exists(ch, hoid);
+ ASSERT_EQ(true, exists);
+ }
+ {
+ uint64_t offs = 0;
+ bufferlist bl;
+ const int size = 0x100;
+ bufferptr ap(size);
+ memset(ap.c_str(), 'a', size);
+ bl.append(ap);
+ int i = 0;
+ uint64_t blob_size = 524288;
+ uint64_t total = 0;
+ for (i = 0; i <= 512; i++) {
+ offs = 0 + i * size;
+ ObjectStore::Transaction t;
+ ghobject_t hoid2 = hoid;
+ hoid2.hobj.snap = i + 1;
+ while (offs < 128 * 1024 * 1024) {
+
+ t.write(cid, hoid, offs, ap.length(), bl);
+ offs += blob_size;
+ total += ap.length();
+ }
+ t.clone(cid, hoid, hoid2);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ cerr << "Total written = " << total << std::endl;
+ }
+ {
+ cerr << "Finalizing" << std::endl;
+ const PerfCounters* logger = store->get_perf_counters();
+ ASSERT_GE(logger->get(l_bluestore_gc_merged), 1024*1024*1024);
+ }
+}
+
+void doManySetAttr(ObjectStore* store,
+ std::function<void(ObjectStore*)> do_check_fn)
+{
+ MixedGenerator gen(447);
+ gen_type rng(time(NULL));
+ coll_t cid(spg_t(pg_t(0, 447), shard_id_t::NO_SHARD));
+
+ SyntheticWorkloadState test_obj(store, &gen, &rng, cid, 0, 0, 0);
+ test_obj.init();
+ size_t object_count = 256;
+ for (size_t i = 0; i < object_count; ++i) {
+ if (!(i % 10)) cerr << "seeding object " << i << std::endl;
+ test_obj.touch();
+ }
+ for (size_t i = 0; i < object_count; ++i) {
+ if (!(i % 100)) {
+ cerr << "Op " << i << std::endl;
+ test_obj.print_internal_state();
+ }
+ test_obj.set_fixed_attrs(1024, 64, 4096); // 1024 attributes, 64 bytes name and 4K value
+ }
+ test_obj.wait_for_done();
+
+ std::cout << "done" << std::endl;
+ do_check_fn(store);
+ 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;
+ }
+ do_check_fn(store);
+ test_obj.shutdown();
+}
+
+TEST_P(StoreTestSpecificAUSize, SpilloverTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_db_create", "true");
+ SetVal(g_conf(), "bluestore_block_db_size", "3221225472");
+ SetVal(g_conf(), "bluestore_volume_selection_policy", "rocksdb_original");
+
+ g_conf().apply_changes(nullptr);
+
+ StartDeferred(65536);
+ doManySetAttr(store.get(),
+ [&](ObjectStore* _store) {
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (_store);
+ ceph_assert(bstore);
+ bstore->compact();
+ const PerfCounters* logger = bstore->get_bluefs_perf_counters();
+ //experimentally it was discovered that this case results in 400+MB spillover
+ //using lower 300MB threshold just to be safe enough
+ std::cout << "db_used:" << logger->get(l_bluefs_db_used_bytes) << std::endl;
+ std::cout << "slow_used:" << logger->get(l_bluefs_slow_used_bytes) << std::endl;
+
+ // Disabling any validation/assertion for now as it looks like
+ // we're unable to 100% force RocksDB to spillover.
+ // Leaving test case hoping to fix that one day though.
+ //ASSERT_GE(logger->get(l_bluefs_slow_used_bytes), 16 * 1024 * 1024);
+ }
+ );
+}
+
+TEST_P(StoreTestSpecificAUSize, SpilloverFixedTest) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_db_create", "true");
+ SetVal(g_conf(), "bluestore_block_db_size", "3221225472");
+ SetVal(g_conf(), "bluestore_volume_selection_policy", "use_some_extra");
+ SetVal(g_conf(), "bluestore_volume_selection_reserved", "1"); // just use non-zero to enable
+
+ g_conf().apply_changes(nullptr);
+
+ StartDeferred(65536);
+ doManySetAttr(store.get(),
+ [&](ObjectStore* _store) {
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (_store);
+ ceph_assert(bstore);
+ bstore->compact();
+ const PerfCounters* logger = bstore->get_bluefs_perf_counters();
+ ASSERT_EQ(0, logger->get(l_bluefs_slow_used_bytes));
+ }
+ );
+}
+
+TEST_P(StoreTestSpecificAUSize, SpilloverFixed2Test) {
+ if (string(GetParam()) != "bluestore")
+ return;
+
+ SetVal(g_conf(), "bluestore_block_db_create", "true");
+ SetVal(g_conf(), "bluestore_block_db_size", "3221225472");
+ SetVal(g_conf(), "bluestore_volume_selection_policy", "use_some_extra");
+ //default 2.0 factor results in too high threshold, using less value
+ // that results in less but still present spillover.
+ SetVal(g_conf(), "bluestore_volume_selection_reserved_factor", "0.5");
+
+ g_conf().apply_changes(nullptr);
+
+ StartDeferred(65536);
+ doManySetAttr(store.get(),
+ [&](ObjectStore* _store) {
+
+ BlueStore* bstore = dynamic_cast<BlueStore*> (_store);
+ ceph_assert(bstore);
+ bstore->compact();
+ const PerfCounters* logger = bstore->get_bluefs_perf_counters();
+ ASSERT_LE(logger->get(l_bluefs_slow_used_bytes), 300 * 1024 * 1024); // see SpilloverTest for 300MB choice rationale
+ }
+ );
+}
+
+#endif // WITH_BLUESTORE
int main(int argc, char **argv) {
vector<const char*> args;
argv_to_vec(argc, (const char **)argv, args);
- env_to_vec(args);
auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
- CODE_ENVIRONMENT_UTILITY, 0);
+ CODE_ENVIRONMENT_UTILITY,
+ CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
common_init_finish(g_ceph_context);
- g_ceph_context->_conf->set_val("osd_journal_size", "400");
- g_ceph_context->_conf->set_val("filestore_index_retry_probability", "0.5");
- g_ceph_context->_conf->set_val("filestore_op_thread_timeout", "1000");
- g_ceph_context->_conf->set_val("filestore_op_thread_suicide_timeout", "10000");
- //g_ceph_context->_conf->set_val("filestore_fiemap", "true");
- g_ceph_context->_conf->set_val("bluestore_fsck_on_mount", "true");
- g_ceph_context->_conf->set_val("bluestore_fsck_on_umount", "true");
- g_ceph_context->_conf->set_val("bluestore_debug_misc", "true");
- g_ceph_context->_conf->set_val("bluestore_debug_small_allocations", "4");
- g_ceph_context->_conf->set_val("bluestore_debug_freelist", "true");
- g_ceph_context->_conf->set_val("bluestore_clone_cow", "true");
- g_ceph_context->_conf->set_val("bluestore_max_alloc_size", "196608");
+ // make sure we can adjust any config settings
+ g_ceph_context->_conf._clear_safe_to_start_threads();
+
+ g_ceph_context->_conf.set_val_or_die("osd_journal_size", "400");
+ g_ceph_context->_conf.set_val_or_die("filestore_index_retry_probability", "0.5");
+ g_ceph_context->_conf.set_val_or_die("filestore_op_thread_timeout", "1000");
+ g_ceph_context->_conf.set_val_or_die("filestore_op_thread_suicide_timeout", "10000");
+ //g_ceph_context->_conf.set_val_or_die("filestore_fiemap", "true");
+ g_ceph_context->_conf.set_val_or_die("bluestore_fsck_on_mkfs", "false");
+ g_ceph_context->_conf.set_val_or_die("bluestore_fsck_on_mount", "false");
+ g_ceph_context->_conf.set_val_or_die("bluestore_fsck_on_umount", "false");
+ g_ceph_context->_conf.set_val_or_die("bluestore_debug_misc", "true");
+ g_ceph_context->_conf.set_val_or_die("bluestore_debug_small_allocations", "4");
+ g_ceph_context->_conf.set_val_or_die("bluestore_debug_freelist", "true");
+ g_ceph_context->_conf.set_val_or_die("bluestore_clone_cow", "true");
+ g_ceph_context->_conf.set_val_or_die("bluestore_max_alloc_size", "196608");
// set small cache sizes so we see trimming during Synthetic tests
- g_ceph_context->_conf->set_val("bluestore_cache_size_hdd", "4000000");
- g_ceph_context->_conf->set_val("bluestore_cache_size_ssd", "4000000");
+ g_ceph_context->_conf.set_val_or_die("bluestore_cache_size_hdd", "4000000");
+ g_ceph_context->_conf.set_val_or_die("bluestore_cache_size_ssd", "4000000");
// very short *_max prealloc so that we fall back to async submits
- g_ceph_context->_conf->set_val("bluestore_blobid_prealloc", "10");
- g_ceph_context->_conf->set_val("bluestore_nid_prealloc", "10");
- g_ceph_context->_conf->set_val("bluestore_debug_randomize_serial_transaction",
+ g_ceph_context->_conf.set_val_or_die("bluestore_blobid_prealloc", "10");
+ g_ceph_context->_conf.set_val_or_die("bluestore_nid_prealloc", "10");
+ g_ceph_context->_conf.set_val_or_die("bluestore_debug_randomize_serial_transaction",
"10");
- g_ceph_context->_conf->set_val("bdev_debug_aio", "true");
+ g_ceph_context->_conf.set_val_or_die("bdev_debug_aio", "true");
// specify device size
- g_ceph_context->_conf->set_val("bluestore_block_size", "10240000000");
+ g_ceph_context->_conf.set_val_or_die("bluestore_block_size",
+ stringify(DEF_STORE_TEST_BLOCKDEV_SIZE));
- g_ceph_context->_conf->set_val(
+ g_ceph_context->_conf.set_val_or_die(
"enable_experimental_unrecoverable_data_corrupting_features", "*");
- g_ceph_context->_conf->apply_changes(NULL);
+ g_ceph_context->_conf.apply_changes(nullptr);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();