2020-08-04 09:15:36 +05:30
|
|
|
#include <chrono>
|
|
|
|
#include <random>
|
2020-07-23 14:41:01 +05:30
|
|
|
#include "damage_generator.h"
|
|
|
|
|
|
|
|
using namespace thin_provisioning;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
void find_blocks(space_map::ptr sm,
|
|
|
|
block_address nr_blocks,
|
|
|
|
ref_t expected,
|
|
|
|
std::set<block_address> &found) {
|
|
|
|
block_address sm_size = sm->get_nr_blocks();
|
|
|
|
base::run_set<block_address> visited;
|
|
|
|
block_address nr_visited = 0;
|
|
|
|
|
2020-08-04 09:15:36 +05:30
|
|
|
uint64_t rand_seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());
|
|
|
|
std::mt19937 rand_engine(rand_seed);
|
|
|
|
|
2020-07-23 14:41:01 +05:30
|
|
|
while (nr_blocks) {
|
|
|
|
if (nr_visited == sm_size)
|
|
|
|
break;
|
|
|
|
|
2020-08-04 09:15:36 +05:30
|
|
|
block_address b = rand_engine() % sm_size;
|
2020-07-23 14:41:01 +05:30
|
|
|
if (visited.member(b))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ref_t c = sm->get_count(b);
|
|
|
|
if (c == expected) {
|
|
|
|
found.insert(b);
|
|
|
|
--nr_blocks;
|
|
|
|
}
|
|
|
|
|
|
|
|
visited.add(b);
|
|
|
|
++nr_visited;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nr_blocks) {
|
|
|
|
ostringstream out;
|
|
|
|
out << "cannot find " << (nr_blocks + found.size())
|
|
|
|
<< " blocks of ref-count " << expected;
|
|
|
|
throw runtime_error(out.str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
|
|
|
|
damage_generator::damage_generator(block_manager::ptr bm)
|
|
|
|
{
|
|
|
|
md_ = metadata::ptr(new metadata(bm, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
void damage_generator::commit()
|
|
|
|
{
|
|
|
|
md_->commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void damage_generator::create_metadata_leaks(block_address nr_leaks,
|
|
|
|
ref_t expected, ref_t actual)
|
|
|
|
{
|
|
|
|
std::set<block_address> leaks;
|
|
|
|
find_blocks(md_->metadata_sm_, nr_leaks, expected, leaks);
|
|
|
|
|
|
|
|
for (auto const &b : leaks)
|
|
|
|
md_->metadata_sm_->set_count(b, actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|