mirror of
https://github.com/ceph/ceph
synced 2025-03-30 15:31:01 +00:00
testsnaps: use self managed snaps and other fixes
Signed-off-by: Samuel Just <samuel.just@dreamhost.com>
This commit is contained in:
parent
94c3763954
commit
c54aa7db3b
@ -159,15 +159,16 @@ void ObjectDesc::update(const ContDesc &next) {
|
||||
|
||||
bool ObjectDesc::check(bufferlist &to_check) {
|
||||
iterator i = begin();
|
||||
uint64_t pos = 0;
|
||||
for (bufferlist::iterator p = to_check.begin();
|
||||
!p.end();
|
||||
++p, ++i) {
|
||||
++p, ++i, ++pos) {
|
||||
if (i.end()) {
|
||||
std::cout << "reached end of iterator first" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (*i != *p) {
|
||||
std::cout << "incorrect buffer num layers: " << layers.size() << std::endl;
|
||||
std::cout << "incorrect buffer at pos " << pos << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "include/rados/librados.h"
|
||||
#include "RadosModel.h"
|
||||
#include "TestOpStat.h"
|
||||
|
||||
@ -21,6 +22,6 @@ void TestOp::finish()
|
||||
}
|
||||
|
||||
void callback(librados::completion_t cb, void *arg) {
|
||||
TestOp *op = (TestOp *) arg;
|
||||
TestOp *op = static_cast<TestOp*>(arg);
|
||||
op->finish();
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ public:
|
||||
Mutex state_lock;
|
||||
Cond wait_cond;
|
||||
map<int, map<string,ObjectDesc> > pool_obj_cont;
|
||||
set<int> snaps;
|
||||
set<string> oid_in_use;
|
||||
set<string> oid_not_in_use;
|
||||
int current_snap;
|
||||
@ -85,6 +84,9 @@ public:
|
||||
int max_in_flight;
|
||||
ContentsGenerator &cont_gen;
|
||||
int seq_num;
|
||||
map<int,uint64_t> snaps;
|
||||
uint64_t seq;
|
||||
|
||||
|
||||
RadosTestContext(const string &pool_name,
|
||||
int max_in_flight,
|
||||
@ -96,7 +98,7 @@ public:
|
||||
pool_name(pool_name),
|
||||
errors(0),
|
||||
max_in_flight(max_in_flight),
|
||||
cont_gen(cont_gen), seq_num(0)
|
||||
cont_gen(cont_gen), seq_num(0), seq(0)
|
||||
{
|
||||
rados.init(id);
|
||||
rados.conf_read_file("ceph.conf");
|
||||
@ -198,27 +200,28 @@ public:
|
||||
void remove_snap(int snap)
|
||||
{
|
||||
map<int, map<string,ObjectDesc> >::iterator next_iter = pool_obj_cont.find(snap);
|
||||
assert(next_iter != pool_obj_cont.end());
|
||||
map<int, map<string,ObjectDesc> >::iterator current_iter = next_iter++;
|
||||
if (next_iter != pool_obj_cont.end()) {
|
||||
map<string,ObjectDesc> ¤t = current_iter->second;
|
||||
map<string,ObjectDesc> &next = next_iter->second;
|
||||
for (map<string,ObjectDesc>::iterator i = current.begin();
|
||||
i != current.end();
|
||||
++i) {
|
||||
if (next.count(i->first) == 0) {
|
||||
next.insert(pair<string,ObjectDesc>(i->first, i->second));
|
||||
}
|
||||
assert(current_iter != pool_obj_cont.end());
|
||||
map<string,ObjectDesc> ¤t = current_iter->second;
|
||||
map<string,ObjectDesc> &next = next_iter->second;
|
||||
for (map<string,ObjectDesc>::iterator i = current.begin();
|
||||
i != current.end();
|
||||
++i) {
|
||||
if (next.count(i->first) == 0) {
|
||||
next.insert(pair<string,ObjectDesc>(i->first, i->second));
|
||||
}
|
||||
}
|
||||
snaps.erase(snap);
|
||||
pool_obj_cont.erase(current_iter);
|
||||
snaps.erase(snap);
|
||||
}
|
||||
|
||||
void add_snap()
|
||||
void add_snap(uint64_t snap)
|
||||
{
|
||||
snaps[current_snap] = snap;
|
||||
current_snap++;
|
||||
pool_obj_cont[current_snap];
|
||||
snaps.insert(current_snap - 1);
|
||||
seq = snap;
|
||||
}
|
||||
|
||||
void roll_back(const string &oid, int snap)
|
||||
@ -237,12 +240,13 @@ public:
|
||||
string oid;
|
||||
ContDesc cont;
|
||||
set<librados::AioCompletion *> waiting;
|
||||
int waiting_on;
|
||||
|
||||
WriteOp(RadosTestContext *context,
|
||||
const string &oid,
|
||||
TestOpStat *stat = 0) :
|
||||
TestOp(context, stat),
|
||||
oid(oid)
|
||||
oid(oid), waiting_on(0)
|
||||
{}
|
||||
|
||||
void _begin()
|
||||
@ -263,16 +267,37 @@ public:
|
||||
}
|
||||
|
||||
context->seq_num++;
|
||||
context->state_lock.Unlock();
|
||||
|
||||
vector<uint64_t> snapset(context->snaps.size());
|
||||
int j = 0;
|
||||
for (map<int,uint64_t>::reverse_iterator i = context->snaps.rbegin();
|
||||
i != context->snaps.rend();
|
||||
++i, ++j) {
|
||||
snapset[j] = i->second;
|
||||
}
|
||||
interval_set<uint64_t> ranges;
|
||||
context->cont_gen.get_ranges(cont, ranges);
|
||||
ContentsGenerator::iterator gen_pos = context->cont_gen.get_iterator(cont);
|
||||
for (interval_set<uint64_t>::iterator i = ranges.begin();
|
||||
i != ranges.end();
|
||||
++i) {
|
||||
++waiting_on;
|
||||
librados::AioCompletion *completion =
|
||||
context->rados.aio_create_completion((void *) this, &callback, &callback);
|
||||
context->rados.aio_create_completion((void *) this, &callback, 0);
|
||||
waiting.insert(completion);
|
||||
}
|
||||
context->state_lock.Unlock();
|
||||
|
||||
int r = context->io_ctx.selfmanaged_snap_set_write_ctx(context->seq, snapset);
|
||||
if (r) {
|
||||
cerr << "r is " << r << " snapset is " << snapset << " seq is " << context->seq << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
ContentsGenerator::iterator gen_pos = context->cont_gen.get_iterator(cont);
|
||||
set<librados::AioCompletion*>::iterator l = waiting.begin();
|
||||
for (interval_set<uint64_t>::iterator i = ranges.begin();
|
||||
i != ranges.end();
|
||||
++i, ++l) {
|
||||
bufferlist to_write;
|
||||
gen_pos.seek(i.get_start());
|
||||
for (uint64_t k = 0; k != i.get_len(); ++k, ++gen_pos) {
|
||||
@ -283,37 +308,35 @@ public:
|
||||
std::cout << "Writing " << context->prefix+oid << " from " << i.get_start()
|
||||
<< " to " << i.get_len() + i.get_start() << " ranges are "
|
||||
<< ranges << std::endl;
|
||||
context->io_ctx.aio_write(context->prefix+oid, completion,
|
||||
context->io_ctx.aio_write(context->prefix+oid, *l,
|
||||
to_write, i.get_len(), i.get_start());
|
||||
waiting.insert(completion);
|
||||
}
|
||||
}
|
||||
|
||||
void _finish()
|
||||
{
|
||||
context->state_lock.Lock();
|
||||
for (set<librados::AioCompletion *>::iterator i = waiting.begin();
|
||||
i != waiting.end();
|
||||
) {
|
||||
if ((*i)->is_complete() && (*i)->is_safe()) {
|
||||
assert(!done);
|
||||
waiting_on--;
|
||||
if (waiting_on == 0) {
|
||||
for (set<librados::AioCompletion *>::iterator i = waiting.begin();
|
||||
i != waiting.end();
|
||||
) {
|
||||
assert((*i)->is_complete());
|
||||
if (int err = (*i)->get_return_value()) {
|
||||
cerr << "Error: oid " << oid << " write returned error code "
|
||||
<< err << std::endl;
|
||||
}
|
||||
(*i)->release();
|
||||
waiting.erase(i++);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (waiting.empty()) {
|
||||
|
||||
context->oid_in_use.erase(oid);
|
||||
context->oid_not_in_use.insert(oid);
|
||||
context->kick();
|
||||
done = true;
|
||||
}
|
||||
context->state_lock.Unlock();
|
||||
|
||||
}
|
||||
|
||||
bool finished()
|
||||
@ -333,6 +356,7 @@ public:
|
||||
string oid;
|
||||
bufferlist result;
|
||||
ObjectDesc old_value;
|
||||
int snap;
|
||||
ReadOp(RadosTestContext *context,
|
||||
const string &oid,
|
||||
TestOpStat *stat = 0) :
|
||||
@ -344,21 +368,33 @@ public:
|
||||
void _begin()
|
||||
{
|
||||
context->state_lock.Lock();
|
||||
if (0 && !(rand() % 4) && !context->snaps.empty()) {
|
||||
snap = rand_choose(context->snaps)->first;
|
||||
} else {
|
||||
snap = -1;
|
||||
}
|
||||
done = 0;
|
||||
completion = context->rados.aio_create_completion((void *) this, &callback, 0);
|
||||
|
||||
context->oid_in_use.insert(oid);
|
||||
context->oid_not_in_use.erase(oid);
|
||||
context->find_object(oid, &old_value);
|
||||
assert(context->find_object(oid, &old_value, snap));
|
||||
|
||||
context->state_lock.Unlock();
|
||||
if (snap >= 0) {
|
||||
context->io_ctx.snap_set_read(context->snaps[snap]);
|
||||
}
|
||||
context->io_ctx.aio_read(context->prefix+oid, completion,
|
||||
&result, context->cont_gen.get_length(old_value.most_recent()), 0);
|
||||
if (snap >= 0) {
|
||||
context->io_ctx.snap_set_read(0);
|
||||
}
|
||||
}
|
||||
|
||||
void _finish()
|
||||
{
|
||||
context->state_lock.Lock();
|
||||
assert(!done);
|
||||
context->oid_in_use.erase(oid);
|
||||
context->oid_not_in_use.insert(oid);
|
||||
if (int err = completion->get_return_value()) {
|
||||
@ -380,6 +416,7 @@ public:
|
||||
cerr << "Object " << oid << " contents " << to_check << " corrupt" << std::endl;
|
||||
context->errors++;
|
||||
}
|
||||
if (context->errors) assert(0);
|
||||
}
|
||||
context->kick();
|
||||
done = true;
|
||||
@ -406,13 +443,13 @@ public:
|
||||
|
||||
void _begin()
|
||||
{
|
||||
uint64_t snap;
|
||||
assert(!context->io_ctx.selfmanaged_snap_create(&snap));
|
||||
|
||||
context->state_lock.Lock();
|
||||
context->add_snap();
|
||||
context->add_snap(snap);
|
||||
context->state_lock.Unlock();
|
||||
|
||||
stringstream snap_name;
|
||||
snap_name << context->prefix << context->current_snap - 1;
|
||||
context->io_ctx.snap_create(snap_name.str().c_str());
|
||||
finish();
|
||||
}
|
||||
|
||||
@ -440,12 +477,11 @@ public:
|
||||
void _begin()
|
||||
{
|
||||
context->state_lock.Lock();
|
||||
uint64_t snap = context->snaps[to_remove];
|
||||
context->remove_snap(to_remove);
|
||||
context->state_lock.Unlock();
|
||||
|
||||
stringstream snap_name;
|
||||
snap_name << context->prefix << to_remove;
|
||||
context->io_ctx.snap_remove(snap_name.str().c_str());
|
||||
assert(!context->io_ctx.selfmanaged_snap_remove(snap));
|
||||
finish();
|
||||
}
|
||||
|
||||
@ -478,11 +514,25 @@ public:
|
||||
context->state_lock.Lock();
|
||||
context->oid_in_use.insert(oid);
|
||||
context->roll_back(oid, roll_back_to);
|
||||
uint64_t snap = context->snaps[roll_back_to];
|
||||
|
||||
vector<uint64_t> snapset(context->snaps.size());
|
||||
int j = 0;
|
||||
for (map<int,uint64_t>::reverse_iterator i = context->snaps.rbegin();
|
||||
i != context->snaps.rend();
|
||||
++i, ++j) {
|
||||
snapset[j] = i->second;
|
||||
}
|
||||
context->state_lock.Unlock();
|
||||
assert(!context->io_ctx.selfmanaged_snap_set_write_ctx(context->seq, snapset));
|
||||
|
||||
|
||||
stringstream snap_name;
|
||||
snap_name << context->prefix << roll_back_to;
|
||||
context->io_ctx.rollback(context->prefix+oid, snap_name.str().c_str());
|
||||
int r = context->io_ctx.selfmanaged_snap_rollback(context->prefix+oid,
|
||||
snap);
|
||||
if (r) {
|
||||
cerr << "r is " << r << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
|
@ -64,13 +64,13 @@ struct SnapTestGenerator : public TestOpGenerator
|
||||
<< context.current_snap << std::endl;
|
||||
return new WriteOp(&context, oid, stats);
|
||||
} else if ((switchval < 45) && !context.snaps.empty()) {
|
||||
int snap = *(rand_choose(context.snaps));
|
||||
int snap = rand_choose(context.snaps)->first;
|
||||
string oid = *(rand_choose(context.oid_not_in_use));
|
||||
cout << "RollingBack " << oid << " to " << snap << std::endl;
|
||||
nextop = new ReadOp(&context, oid, stats);
|
||||
return new RollbackOp(&context, oid, snap);
|
||||
} else if ((switchval < 47) && !context.snaps.empty()) {
|
||||
int snap = *(rand_choose(context.snaps));
|
||||
int snap = rand_choose(context.snaps)->first;
|
||||
cout << "RemovingSnap " << snap << std::endl;
|
||||
return new SnapRemoveOp(&context, snap, stats);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user