Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/Bluestore: More testcases and fixes #22

Merged
merged 5 commits into from
May 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/os/bluestore/BlueStore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -773,10 +773,12 @@ BlueStore::BlueStore(CephContext *cct, const string& path)
min_alloc_size(0)
{
_init_logger();
g_ceph_context->_conf->add_observer(this);
}

BlueStore::~BlueStore()
{
g_ceph_context->_conf->remove_observer(this);
_shutdown_logger();
assert(!mounted);
assert(db == NULL);
Expand All @@ -789,6 +791,10 @@ const char **BlueStore::get_tracked_conf_keys() const
static const char* KEYS[] = {
"bluestore_csum",
"bluestore_csum_type",
"bluestore_compression",
"bluestore_compression_algorithm",
"bluestore_compression_min_blob_size",
"bluestore_compression_max_blob_size",
NULL
};
return KEYS;
Expand Down Expand Up @@ -3017,8 +3023,6 @@ int BlueStore::_read_whole_blob(const bluestore_blob_t* blob, OnodeRef o, bool b

result->clear();

uint64_t block_size = bdev->get_block_size();

uint32_t l = blob->length;
uint64_t ext_pos = 0;
auto it = blob->extents.cbegin();
Expand Down Expand Up @@ -5498,6 +5502,7 @@ void BlueStore::_do_write_big(
}
dout(10) << __func__ << " 0x" << std::hex << offset << "~" << length
<< " max_blob_len 0x" << max_blob_len
<< " compress " << wctx->compress
<< std::dec << dendl;
while (length > 0) {
int64_t blob;
Expand Down Expand Up @@ -5563,17 +5568,19 @@ int BlueStore::_do_alloc_write(
if (newlen < final_length) {
// pad out to min_alloc_size
compressed_bl.append_zero(newlen - rawlen);
dout(20) << __func__ << " compressed 0x" << b->length
dout(20) << __func__ << hex << " compressed 0x" << b->length
<< " -> 0x" << rawlen << " => 0x" << newlen
<< " with " << chdr.type << dendl;
<< " with " << chdr.type
<< dec << dendl;
l = &compressed_bl;
final_length = newlen;
csum_length = newlen;
b->set_flag(bluestore_blob_t::FLAG_COMPRESSED);
} else {
dout(20) << __func__ << " compressed 0x" << l->length() << " -> 0x"
dout(20) << __func__ << hex << " compressed 0x" << l->length() << " -> 0x"
<< rawlen << " with " << chdr.type
<< ", leaving uncompressed" << dendl;
<< ", leaving uncompressed"
<< dec << dendl;
b->set_flag(bluestore_blob_t::FLAG_MUTABLE);
}
} else {
Expand Down
280 changes: 278 additions & 2 deletions src/test/objectstore/store_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,190 @@ TEST_P(StoreTest, BufferCacheReadTest) {
}
}

TEST_P(StoreTest, CompressionTest) {
ObjectStore::Sequencer osr("test");
int r;
coll_t cid;
if(string(GetParam()) != "bluestore")
return;

g_conf->set_val("bluestore_compression", "force");
g_ceph_context->_conf->apply_changes(NULL);

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);
}
{
ObjectStore::Transaction t;
t.create_collection(cid, 0);
cerr << "Creating collection " << cid << std::endl;
r = apply_transaction(store, &osr, std::move(t));
ASSERT_EQ(r, 0);
}
{
bool exists = store->exists(cid, 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));
ASSERT_EQ(r, 0);

exists = store->exists(cid, hoid);
ASSERT_EQ(true, exists);
}
std::string data;
data.resize(0x10000 * 4);
for(size_t i = 0;i < data.size(); i++)
data[i] = i / 256;
{
ObjectStore::Transaction t;
bufferlist bl, newdata;
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));
ASSERT_EQ(r, 0);

r = store->read(cid, hoid, 0, data.size() , newdata);
ASSERT_EQ(r, (int)data.size());
{
bufferlist expected;
expected.append(data);
ASSERT_TRUE(newdata.contents_equal(expected));
}
newdata.clear();
r = store->read(cid, hoid, 0, 711 , newdata);
ASSERT_EQ(r, 711);
{
bufferlist expected;
expected.append(data.substr(0,711));
ASSERT_TRUE(newdata.contents_equal(expected));
}
newdata.clear();
r = store->read(cid, hoid, 0xf00f, data.size(), newdata);
ASSERT_EQ(r, int(data.size() - 0xf00f) );
{
bufferlist expected;
expected.append(data.substr(0xf00f));
ASSERT_TRUE(newdata.contents_equal(expected));
}
}
std::string data2;
data2.resize(0x10000 * 4 - 0x9000);
for(size_t i = 0;i < data2.size(); i++)
data2[i] = (i+1) / 256;
{
ObjectStore::Transaction t;
bufferlist bl, newdata;
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));
ASSERT_EQ(r, 0);

r = store->read(cid, hoid, 0, 0x10000, newdata);
ASSERT_EQ(r, (int)0x10000);
{
bufferlist expected;
expected.append(data.substr(0, 0x8000));
expected.append(data2.substr(0, 0x8000));
ASSERT_TRUE(newdata.contents_equal(expected));
}
newdata.clear();
r = store->read(cid, hoid, 0x9000, 711 , newdata);
ASSERT_EQ(r, 711);
{
bufferlist expected;
expected.append(data2.substr(0x1000,711));
ASSERT_TRUE(newdata.contents_equal(expected));
}
newdata.clear();
r = store->read(cid, hoid, 0x0, 0x40000, newdata);
ASSERT_EQ(r, int(0x40000) );
{
bufferlist expected;
expected.append(data.substr(0, 0x8000));
expected.append(data2.substr(0, 0x37000));
expected.append(data.substr(0x3f000, 0x1000));
ASSERT_TRUE(newdata.contents_equal(expected));
}
}
data2.resize(0x3f000);
for(size_t i = 0;i < data2.size(); i++)
data2[i] = (i+2) / 256;
{
ObjectStore::Transaction t;
bufferlist bl, newdata;
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));
ASSERT_EQ(r, 0);

r = store->read(cid, hoid, 0, 0x3e000 - 1, newdata);
ASSERT_EQ(r, (int)0x3e000 - 1);
{
bufferlist expected;
expected.append(data2.substr(0, 0x3e000 - 1));
ASSERT_TRUE(newdata.contents_equal(expected));
}
newdata.clear();
r = store->read(cid, hoid, 0x3e000-1, 0x2001, newdata);
ASSERT_EQ(r, 0x2001);
{
bufferlist expected;
expected.append(data2.substr(0x3e000-1, 0x1001));
expected.append(data.substr(0x3f000, 0x1000));
ASSERT_TRUE(newdata.contents_equal(expected));
}
newdata.clear();
r = store->read(cid, hoid, 0x0, 0x40000, newdata);
ASSERT_EQ(r, int(0x40000) );
{
bufferlist expected;
expected.append(data2.substr(0, 0x3f000));
expected.append(data.substr(0x3f000, 0x1000));
ASSERT_TRUE(newdata.contents_equal(expected));
}
}
data.resize(0x1001);
for(size_t i = 0;i < data.size(); i++)
data[i] = (i+3) / 256;
{
ObjectStore::Transaction t;
bufferlist bl, newdata;
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));
ASSERT_EQ(r, 0);

r = store->read(cid, hoid, 0x3e000, 0x2000, newdata);
ASSERT_EQ(r, (int)0x2000);
{
bufferlist expected;
expected.append(data2.substr(0x3e000, 0x1000 - 1));
expected.append(data.substr(0, 0x1001));
ASSERT_TRUE(newdata.contents_equal(expected));
}
}
{
ObjectStore::Transaction t;
t.remove(cid, hoid);
t.remove_collection(cid);
cerr << "Cleaning" << std::endl;
r = apply_transaction(store, &osr, std::move(t));
ASSERT_EQ(r, 0);
}
g_conf->set_val("bluestore_compression", "none");
g_ceph_context->_conf->apply_changes(NULL);
}

TEST_P(StoreTest, SimpleObjectTest) {
ObjectStore::Sequencer osr("test");
int r;
Expand Down Expand Up @@ -821,6 +1005,57 @@ TEST_P(StoreTest, SimpleObjectTest) {
in.hexdump(cout);
ASSERT_TRUE(in.contents_equal(bl));
}
{
//verifying unaligned csums
std::string s1("1"), s2(0x1000, '2'), s3("00");
{
ObjectStore::Transaction t;
bufferlist bl;
bl.append(s1);
bl.append(s2);
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));
ASSERT_EQ(r, 0);
}

bufferlist in, exp1, exp2, exp3;
exp1.append(s1);
exp2.append(s2);
exp3.append(s3);
r = store->read(cid, hoid, 0x1000-1, 1, in);
ASSERT_EQ(1, r);
ASSERT_TRUE(in.contents_equal(exp1));
in.clear();
r = store->read(cid, hoid, 0x1000, 0x1000, in);
ASSERT_EQ(0x1000, r);
ASSERT_TRUE(in.contents_equal(exp2));

{
ObjectStore::Transaction t;
bufferlist bl;
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));
ASSERT_EQ(r, 0);
}
in.clear();
r = store->read(cid, hoid, 1, 2, in);
ASSERT_EQ(2, r);
ASSERT_TRUE(in.contents_equal(exp3));
in.clear();
r = store->read(cid, hoid, 0x1000-1, 1, in);
ASSERT_EQ(1, r);
ASSERT_TRUE(in.contents_equal(exp1));
in.clear();
r = store->read(cid, hoid, 0x1000, 0x1000, in);
ASSERT_EQ(0x1000, r);
ASSERT_TRUE(in.contents_equal(exp2));

}

{
ObjectStore::Transaction t;
t.remove(cid, hoid);
Expand Down Expand Up @@ -2943,7 +3178,8 @@ class SyntheticWorkloadState {
}
};

TEST_P(StoreTest, Synthetic) {
void doSyntheticTest(boost::scoped_ptr<ObjectStore>& store)
{
ObjectStore::Sequencer osr("test");
MixedGenerator gen(555);
gen_type rng(time(NULL));
Expand Down Expand Up @@ -2986,6 +3222,28 @@ TEST_P(StoreTest, Synthetic) {
test_obj.shutdown();
}

TEST_P(StoreTest, Synthetic) {
doSyntheticTest(store);
}

TEST_P(StoreTest, SyntheticCompressed) {
if(string(GetParam()) != "bluestore")
return;
g_conf->set_val("bluestore_compression", "force");
g_ceph_context->_conf->apply_changes(NULL);

doSyntheticTest(store);

g_conf->set_val("bluestore_compression_algorithm", "zlib");
g_ceph_context->_conf->apply_changes(NULL);

doSyntheticTest(store);

g_conf->set_val("bluestore_compression", "none");
g_conf->set_val("bluestore_compression_algorithm", "snappy");
g_ceph_context->_conf->apply_changes(NULL);
}

TEST_P(StoreTest, AttrSynthetic) {
ObjectStore::Sequencer osr("test");
MixedGenerator gen(447);
Expand Down Expand Up @@ -4005,6 +4263,24 @@ int main(int argc, char **argv) {

global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
common_init_finish(g_ceph_context);

const char* env = getenv("CEPH_LIB");
std::string directory(env ? env : ".libs");
string mkdir_compressor = "mkdir -p " + directory + "/compressor";
int r = system(mkdir_compressor.c_str());
(void)r;

string cp_libceph_snappy = "cp " + directory + "/libceph_snappy.so* " + directory + "/compressor/";
r = system(cp_libceph_snappy.c_str());
(void)r;

string cp_libceph_zlib = "cp " + directory + "/libceph_zlib.so* " + directory + "/compressor/";
r = system(cp_libceph_zlib.c_str());
(void)r;

g_ceph_context->_conf->set_val("plugin_dir", directory, false, false);


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");
Expand All @@ -4021,7 +4297,7 @@ int main(int argc, char **argv) {
g_ceph_context->_conf->apply_changes(NULL);

::testing::InitGoogleTest(&argc, argv);
int r = RUN_ALL_TESTS();
r = RUN_ALL_TESTS();
g_ceph_context->put();
return r;
}
Expand Down