checking during IO sequences (disabled by default).
Signed-off-by: Connor Fawcett <connorfa@uk.ibm.com>
Sequence sequence, std::pair<int, int> obj_size_range,
std::optional<std::pair<int, int>> km,
std::optional<std::pair<std::string_view, std::string_view>> mappinglayers,
- int seed) {
+ int seed,
+ bool check_consistency) {
switch (sequence) {
case Sequence::SEQUENCE_SEQ0:
[[fallthrough]];
[[fallthrough]];
case Sequence::SEQUENCE_SEQ14:
return std::make_unique<ReadInjectSequence>(obj_size_range, seed,
- sequence, km, mappinglayers);
+ sequence, km, mappinglayers, check_consistency);
case Sequence::SEQUENCE_SEQ10:
- return std::make_unique<Seq10>(obj_size_range, seed, km, mappinglayers);
+ return std::make_unique<Seq10>(obj_size_range, seed, km, mappinglayers, check_consistency);
default:
ceph_abort_msg("Unrecognised sequence");
}
}
-EcIoSequence::EcIoSequence(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed),
+EcIoSequence::EcIoSequence(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency),
setup_inject(false),
clear_inject(false),
shard_to_inject(std::nullopt) {}
int seed,
Sequence s,
std::optional<std::pair<int, int>> km,
- std::optional<std::pair<std::string_view, std::string_view>> mappinglayers)
- : EcIoSequence(obj_size_range, seed) {
- child_sequence = IoSequence::generate_sequence(s, obj_size_range, seed);
+ std::optional<std::pair<std::string_view, std::string_view>> mappinglayers,
+ bool check_consistency)
+ : EcIoSequence(obj_size_range, seed, check_consistency) {
+ child_sequence = IoSequence::generate_sequence(s, obj_size_range, seed, check_consistency);
select_random_data_shard_to_inject_read_error(km, mappinglayers);
generate_random_read_inject_type();
}
ceph::io_exerciser::Seq10::Seq10(
std::pair<int, int> obj_size_range, int seed,
std::optional<std::pair<int, int>> km,
- std::optional<std::pair<std::string_view, std::string_view>> mappinglayers)
- : EcIoSequence(obj_size_range, seed),
+ std::optional<std::pair<std::string_view, std::string_view>> mappinglayers,
+ bool check_consistency)
+ : EcIoSequence(obj_size_range, seed, check_consistency),
offset(0),
length(1),
inject_error_done(false),
std::optional<std::pair<int, int>> km,
std::optional<std::pair<std::string_view, std::string_view>>
mappinglayers,
- int seed);
+ int seed,
+ bool check_consistency);
protected:
bool setup_inject;
std::optional<uint64_t> shard_to_inject;
InjectOpType inject_op_type;
- EcIoSequence(std::pair<int, int> obj_size_range, int seed);
+ EcIoSequence(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
// Writes cannot be sent to injected on shard zero, so selections seperated
// out
std::pair<int, int> obj_size_range, int seed, Sequence s,
std::optional<std::pair<int, int>> km,
std::optional<std::pair<std::string_view, std::string_view>>
- mappinglayers);
+ mappinglayers,
+ bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
Seq10(std::pair<int, int> obj_size_range, int seed,
std::optional<std::pair<int, int>> km,
std::optional<std::pair<std::string_view, std::string_view>>
- mappinglayers);
+ mappinglayers,
+ bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
using BarrierOp = ceph::io_exerciser::BarrierOp;
using CreateOp = ceph::io_exerciser::CreateOp;
using RemoveOp = ceph::io_exerciser::RemoveOp;
+using ConsistencyOp = ceph::io_exerciser::ConsistencyOp;
using SingleReadOp = ceph::io_exerciser::SingleReadOp;
using DoubleReadOp = ceph::io_exerciser::DoubleReadOp;
using TripleReadOp = ceph::io_exerciser::TripleReadOp;
}
}
+ConsistencyOp::ConsistencyOp() : TestOp<OpType::Consistency>() {}
+
+std::unique_ptr<ConsistencyOp> ConsistencyOp::generate() {
+ return std::make_unique<ConsistencyOp>();
+}
+
+std::string ConsistencyOp::to_string(uint64_t block_size) const {
+ return "Consistency";
+}
+
template <OpType opType, int numIOs>
std::string ceph::io_exerciser::ReadWriteOp<opType, numIOs>::to_string(
uint64_t block_size) const {
std::string to_string(uint64_t block_size) const override;
};
+class ConsistencyOp : public TestOp<OpType::Consistency> {
+ public:
+ ConsistencyOp();
+ static std::unique_ptr<ConsistencyOp> generate();
+ std::string to_string(uint64_t block_size) const override;
+ };
+
template <OpType opType, int numIOs>
class ReadWriteOp : public TestOp<opType> {
public:
#include <algorithm>
using IoOp = ceph::io_exerciser::IoOp;
+using OpType = ceph::io_exerciser::OpType;
using Sequence = ceph::io_exerciser::Sequence;
using IoSequence = ceph::io_exerciser::IoSequence;
}
std::unique_ptr<IoSequence> IoSequence::generate_sequence(
- Sequence s, std::pair<int, int> obj_size_range, int seed) {
+ Sequence s, std::pair<int, int> obj_size_range, int seed, bool check_consistency) {
switch (s) {
case Sequence::SEQUENCE_SEQ0:
- return std::make_unique<Seq0>(obj_size_range, seed);
+ return std::make_unique<Seq0>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ1:
- return std::make_unique<Seq1>(obj_size_range, seed);
+ return std::make_unique<Seq1>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ2:
- return std::make_unique<Seq2>(obj_size_range, seed);
+ return std::make_unique<Seq2>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ3:
- return std::make_unique<Seq3>(obj_size_range, seed);
+ return std::make_unique<Seq3>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ4:
- return std::make_unique<Seq4>(obj_size_range, seed);
+ return std::make_unique<Seq4>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ5:
- return std::make_unique<Seq5>(obj_size_range, seed);
+ return std::make_unique<Seq5>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ6:
- return std::make_unique<Seq6>(obj_size_range, seed);
+ return std::make_unique<Seq6>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ7:
- return std::make_unique<Seq7>(obj_size_range, seed);
+ return std::make_unique<Seq7>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ8:
- return std::make_unique<Seq8>(obj_size_range, seed);
+ return std::make_unique<Seq8>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ9:
- return std::make_unique<Seq9>(obj_size_range, seed);
+ return std::make_unique<Seq9>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ10:
ceph_abort_msg(
"Sequence 10 only supported for erasure coded pools "
"through the EcIoSequence interface");
return nullptr;
case Sequence::SEQUENCE_SEQ11:
- return std::make_unique<Seq11>(obj_size_range, seed);
+ return std::make_unique<Seq11>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ12:
- return std::make_unique<Seq12>(obj_size_range, seed);
+ return std::make_unique<Seq12>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ13:
- return std::make_unique<Seq13>(obj_size_range, seed);
+ return std::make_unique<Seq13>(obj_size_range, seed, check_consistency);
case Sequence::SEQUENCE_SEQ14:
- return std::make_unique<Seq14>(obj_size_range, seed);
+ return std::make_unique<Seq14>(obj_size_range, seed, check_consistency);
default:
break;
}
return nullptr;
}
-IoSequence::IoSequence(std::pair<int, int> obj_size_range, int seed)
+IoSequence::IoSequence(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
: min_obj_size(obj_size_range.first),
max_obj_size(obj_size_range.second),
create(true),
barrier(false),
done(false),
remove(false),
+ consistency(false),
+ consistency_in_progress(false),
+ consistency_request_sent(false),
+ check_consistency(check_consistency),
obj_size(min_obj_size),
step(-1),
seed(seed) {
return BarrierOp::generate();
}
+std::unique_ptr<IoOp> IoSequence::process_remove() {
+ if (check_consistency) {
+ if (!consistency_in_progress) {
+ consistency_in_progress = true;
+ consistency_request_sent = true;
+ return ConsistencyOp::generate();
+ }
+
+ if (consistency_request_sent) {
+ consistency_request_sent = false;
+ return BarrierOp::generate();
+ }
+ }
+
+ // Getting here means consistency and barriers have been applied if required
+ remove = false;
+ consistency_in_progress = false;
+ return RemoveOp::generate();
+}
+
Sequence IoSequence::getNextSupportedSequenceId() const {
Sequence sequence = get_id();
++sequence;
return Sequence::SEQUENCE_END;
}
-
std::unique_ptr<IoOp> IoSequence::next() {
step++;
if (remove) {
- remove = false;
- return RemoveOp::generate();
+ return process_remove();
}
if (barrier) {
barrier = false;
return BarrierOp::generate();
}
+ if (consistency) {
+ consistency = false;
+ barrier = true;
+ return ConsistencyOp::generate();
+ }
if (done) {
return DoneOp::generate();
}
return _next();
}
-ceph::io_exerciser::Seq0::Seq0(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), offset(0) {
+ceph::io_exerciser::Seq0::Seq0(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), offset(0) {
select_random_object_size();
length = 1 + rng(obj_size - 1);
}
return r;
}
-ceph::io_exerciser::Seq1::Seq1(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed) {
+ceph::io_exerciser::Seq1::Seq1(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency) {
select_random_object_size();
count = 3 * obj_size;
}
}
}
-ceph::io_exerciser::Seq2::Seq2(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), offset(0), length(0) {}
+ceph::io_exerciser::Seq2::Seq2(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), offset(0), length(0) {}
Sequence ceph::io_exerciser::Seq2::get_id() const {
return Sequence::SEQUENCE_SEQ2;
return SingleReadOp::generate(offset, length);
}
-ceph::io_exerciser::Seq3::Seq3(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), offset1(0), offset2(0) {
+ceph::io_exerciser::Seq3::Seq3(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), offset1(0), offset2(0) {
set_min_object_size(2);
}
return DoubleReadOp::generate(offset1, 1, offset1 + offset2, 1);
}
-ceph::io_exerciser::Seq4::Seq4(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), offset1(0), offset2(1) {
+ceph::io_exerciser::Seq4::Seq4(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), offset1(0), offset2(1) {
set_min_object_size(3);
}
(offset1 * 2 + offset2) / 2, 1);
}
-ceph::io_exerciser::Seq5::Seq5(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed),
+ceph::io_exerciser::Seq5::Seq5(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency),
offset(0),
length(1),
doneread(false),
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
+ consistency = check_consistency;
return BarrierOp::generate();
}
doneread = true;
return r;
}
-ceph::io_exerciser::Seq6::Seq6(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed),
+ceph::io_exerciser::Seq6::Seq6(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency),
offset(0),
length(1),
doneread(false),
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
+ consistency = check_consistency;
return BarrierOp::generate();
}
doneread = true;
return r;
}
-ceph::io_exerciser::Seq7::Seq7(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed) {
+ceph::io_exerciser::Seq7::Seq7(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency) {
set_min_object_size(2);
offset = obj_size;
}
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
+ consistency = check_consistency;
return BarrierOp::generate();
}
doneread = true;
return DoubleWriteOp::generate(offset, 1, obj_size / 2, 1);
}
-ceph::io_exerciser::Seq8::Seq8(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), offset1(0), offset2(1) {
+ceph::io_exerciser::Seq8::Seq8(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), offset1(0), offset2(1) {
set_min_object_size(3);
}
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
+ consistency = check_consistency;
return BarrierOp::generate();
}
doneread = true;
(offset1 * 2 + offset2) / 2, 1);
}
-ceph::io_exerciser::Seq9::Seq9(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), offset(0), length(0) {}
+ceph::io_exerciser::Seq9::Seq9(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), offset(0), length(0) {}
Sequence ceph::io_exerciser::Seq9::get_id() const {
return Sequence::SEQUENCE_SEQ9;
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
+ consistency = check_consistency;
return BarrierOp::generate();
}
doneread = true;
return SingleWriteOp::generate(offset, length);
}
-ceph::io_exerciser::Seq11::Seq11(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed),
+ceph::io_exerciser::Seq11::Seq11(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency),
count(0),
doneread(false),
donebarrier(false) {}
return SingleAppendOp::generate(obj_size);
}
-ceph::io_exerciser::Seq12::Seq12(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), count(0), overlap(1), doneread(false) {}
+ceph::io_exerciser::Seq12::Seq12(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), count(0), overlap(1), doneread(false) {}
Sequence ceph::io_exerciser::Seq12::get_id() const {
return Sequence::SEQUENCE_SEQ12;
obj_size + overlap);
}
-ceph::io_exerciser::Seq13::Seq13(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(obj_size_range, seed), count(0), gap(1), doneread(false) {
+ceph::io_exerciser::Seq13::Seq13(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(obj_size_range, seed, check_consistency), count(0), gap(1), doneread(false) {
set_min_object_size(2);
}
return SingleWriteOp::generate((count * obj_size) + gap, obj_size - gap);
}
-ceph::io_exerciser::Seq14::Seq14(std::pair<int, int> obj_size_range, int seed)
- : IoSequence(std::make_pair(0, obj_size_range.second), seed),
+ceph::io_exerciser::Seq14::Seq14(std::pair<int, int> obj_size_range, int seed, bool check_consistency)
+ : IoSequence(std::make_pair(0, obj_size_range.second), seed, check_consistency),
offset(0),
step(1) {
startrng = std::default_random_engine(seed);
std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq14::_next() {
if (offset >= target_obj_size) {
if (!doneread) {
+ consistency = check_consistency;
+ barrier = check_consistency;
doneread = true;
return SingleReadOp::generate(0, current_size);
}
virtual bool is_supported(Sequence sequence) const;
static std::unique_ptr<IoSequence> generate_sequence(
- Sequence s, std::pair<int, int> obj_size_range, int seed);
+ Sequence s, std::pair<int, int> obj_size_range, int seed, bool check_consistency);
protected:
uint64_t min_obj_size;
bool barrier;
bool done;
bool remove;
+ bool consistency;
+ bool consistency_in_progress;
+ bool consistency_request_sent;
+ bool check_consistency;
uint64_t obj_size;
int step;
int seed;
ceph::util::random_number_generator<int> rng =
ceph::util::random_number_generator<int>();
- IoSequence(std::pair<int, int> obj_size_range, int seed);
+ IoSequence(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
virtual std::unique_ptr<IoOp> _next() = 0;
void set_max_object_size(uint64_t size);
void select_random_object_size();
std::unique_ptr<IoOp> increment_object_size();
+ std::unique_ptr<IoOp> process_remove();
};
class Seq0 : public IoSequence {
public:
- Seq0(std::pair<int, int> obj_size_range, int seed);
+ Seq0(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq1 : public IoSequence {
public:
- Seq1(std::pair<int, int> obj_size_range, int seed);
+ Seq1(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq2 : public IoSequence {
public:
- Seq2(std::pair<int, int> obj_size_range, int seed);
+ Seq2(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq3 : public IoSequence {
public:
- Seq3(std::pair<int, int> obj_size_range, int seed);
+ Seq3(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq4 : public IoSequence {
public:
- Seq4(std::pair<int, int> obj_size_range, int seed);
+ Seq4(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq5 : public IoSequence {
public:
- Seq5(std::pair<int, int> obj_size_range, int seed);
+ Seq5(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq6 : public IoSequence {
public:
- Seq6(std::pair<int, int> obj_size_range, int seed);
+ Seq6(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq7 : public IoSequence {
public:
- Seq7(std::pair<int, int> obj_size_range, int seed);
+ Seq7(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
class Seq8 : public IoSequence {
public:
- Seq8(std::pair<int, int> obj_size_range, int seed);
+ Seq8(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
bool donebarrier = false;
public:
- Seq9(std::pair<int, int> obj_size_range, int seed);
+ Seq9(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
bool donebarrier = false;
public:
- Seq11(std::pair<int, int> obj_size_range, int seed);
+ Seq11(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
bool donebarrier = false;
public:
- Seq12(std::pair<int, int> obj_size_range, int seed);
+ Seq12(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
bool donebarrier = false;
public:
- Seq13(std::pair<int, int> obj_size_range, int seed);
+ Seq13(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
Sequence get_id() const override;
std::string get_name() const override;
bool doneread = false;
public:
- Seq14(std::pair<int, int> obj_size_range, int seed);
+ Seq14(std::pair<int, int> obj_size_range, int seed, bool check_consistency);
void setup_starts();
Sequence get_id() const override;
Barrier, // Barrier - all prior I/Os must complete
Create, // Create object and pattern with data
Remove, // Remove object
+ Consistency, // Check consistency of an object
Read, // Read
Read2, // Two reads in a single op
Read3, // Three reads in a single op
return fmt::format_to(ctx.out(), "Create");
case ceph::io_exerciser::OpType::Remove:
return fmt::format_to(ctx.out(), "Remove");
+ case ceph::io_exerciser::OpType::Consistency:
+ return fmt::format_to(ctx.out(), "Consistency");
case ceph::io_exerciser::OpType::Read:
return fmt::format_to(ctx.out(), "Read");
case ceph::io_exerciser::OpType::Read2:
#include "common/json/OSDStructures.h"
using RadosIo = ceph::io_exerciser::RadosIo;
+using ConsistencyChecker = ceph::consistency::ConsistencyChecker;
namespace {
template <typename S>
om(std::make_unique<ObjectModel>(oid, block_size, seed)),
db(data_generation::DataGenerator::create_generator(
data_generation::GenerationType::HeaderedSeededRandom, *om)),
+ cc(std::make_unique<ConsistencyChecker>(rados, asio, pool)),
pool(pool),
cached_shard_order(cached_shard_order),
threads(threads),
std::move(wop), 0, nullptr, remove_cb);
break;
}
+
+ case OpType::Consistency: {
+ start_io();
+ bool is_consistent =
+ cc->single_read_and_check_consistency(oid, block_size, 0, 0);
+ ceph_assert(is_consistent);
+ finish_io();
+ break;
+ }
+
case OpType::Read:
[[fallthrough]];
case OpType::Read2:
fmt::format("Unsupported inject operation ({})", op.getOpType()));
break;
}
-}
+}
\ No newline at end of file
#pragma once
#include "ObjectModel.h"
+#include "erasure-code/consistency/ConsistencyChecker.h"
/* Overview
*
boost::asio::io_context& asio;
std::unique_ptr<ObjectModel> om;
std::unique_ptr<ceph::io_exerciser::data_generation::DataGenerator> db;
+ std::unique_ptr<ceph::consistency::ConsistencyChecker> cc;
std::string pool;
std::optional<std::vector<int>> cached_shard_order;
int threads;
${CMAKE_CURRENT_SOURCE_DIR}/ceph_test_rados_io_sequence/ceph_test_rados_io_sequence.cc)
add_dependencies(ceph_test_rados_io_sequence erasure_code_plugins)
target_link_libraries(ceph_test_rados_io_sequence
- librados global object_io_exerciser json_structures)
+ librados global object_io_exerciser json_structures ec_consistency)
install(TARGETS
ceph_test_rados_io_sequence
DESTINATION ${CMAKE_INSTALL_BINDIR})
"number of objects to exercise in parallel")(
"testrecovery",
"Inject errors during sequences to test recovery processes of OSDs")(
+ "checkconsistency",
+ "Test objects for consistency during IO sequences. Disabled by default.")(
"interactive", "interactive mode, execute IO commands from stdin")(
"allow_pool_autoscaling",
"Allows pool autoscaling. Disabled by default.")(
SelectObjectSize& sos, SelectNumThreads& snt, SelectSeqRange& ssr,
ceph::util::random_number_generator<int>& rng, ceph::mutex& lock,
ceph::condition_variable& cond, bool dryrun, bool verbose,
- std::optional<int> seqseed, bool testrecovery)
- : rng(rng), verbose(verbose), seqseed(seqseed), testrecovery(testrecovery) {
+ std::optional<int> seqseed, bool testrecovery, bool checkconsistency)
+ : rng(rng), verbose(verbose), seqseed(seqseed),
+ testrecovery(testrecovery), checkconsistency(checkconsistency) {
if (dryrun) {
exerciser_model = std::make_unique<ceph::io_exerciser::ObjectModel>(
oid, sbs.select(), rng());
if (testrecovery) {
seq = ceph::io_exerciser::EcIoSequence::generate_sequence(
curseq, obj_size_range, pool_km, pool_mappinglayers,
- seqseed.value_or(rng()));
+ seqseed.value_or(rng()), checkconsistency);
} else {
seq = ceph::io_exerciser::IoSequence::generate_sequence(
- curseq, obj_size_range, seqseed.value_or(rng()));
+ curseq, obj_size_range, seqseed.value_or(rng()), checkconsistency);
}
op = seq->next();
if (testrecovery) {
seq = ceph::io_exerciser::EcIoSequence::generate_sequence(
curseq, obj_size_range, pool_km, pool_mappinglayers,
- seqseed.value_or(rng()));
+ seqseed.value_or(rng()), checkconsistency);
} else {
seq = ceph::io_exerciser::IoSequence::generate_sequence(
- curseq, obj_size_range, seqseed.value_or(rng()));
+ curseq, obj_size_range, seqseed.value_or(rng()), checkconsistency);
}
dout(0) << "== " << exerciser_model->get_oid() << " " << curseq << " "
object_name = vm["object"].as<std::string>();
interactive = vm.contains("interactive");
testrecovery = vm.contains("testrecovery");
+ checkconsistency = vm.contains("checkconsistency");
allow_pool_autoscaling = vm.contains("allow_pool_autoscaling");
allow_pool_balancer = vm.contains("allow_pool_balancer");
}
void ceph::io_sequence::tester::TestRunner::list_sequence(bool testrecovery) {
- // List seqeunces
+ // List sequences
std::pair<int, int> obj_size_range = sos.select();
ceph::io_exerciser::Sequence s = ceph::io_exerciser::Sequence::SEQUENCE_BEGIN;
std::unique_ptr<ceph::io_exerciser::IoSequence> seq;
do {
if (testrecovery) {
seq = ceph::io_exerciser::EcIoSequence::generate_sequence(
- s, obj_size_range, km, mappinglayers, seqseed.value_or(rng()));
+ s, obj_size_range, km, mappinglayers, seqseed.value_or(rng()), checkconsistency);
}
else {
seq = ceph::io_exerciser::IoSequence::generate_sequence(
- s, obj_size_range, seqseed.value_or(rng()));
+ s, obj_size_range, seqseed.value_or(rng()), checkconsistency);
}
dout(0) << s << " " << seq->get_name_with_seqseed() << dendl;
test_objects.push_back(
std::make_shared<ceph::io_sequence::tester::TestObject>(
name, rados, asio, sbs, spo, sos, snt, ssr, rng, lock, cond,
- dryrun, verbose, seqseed, testrecovery));
+ dryrun, verbose, seqseed, testrecovery, checkconsistency));
}
catch (const std::runtime_error &e) {
std::cerr << "Error: " << e.what() << std::endl;
bool dryrun,
bool verbose,
std::optional<int> seqseed,
- bool testRecovery);
+ bool testRecovery,
+ bool checkConsistency);
int get_num_io();
bool readyForIo();
std::optional<std::pair<std::string_view, std::string_view>>
pool_mappinglayers;
bool testrecovery;
+ bool checkconsistency;
};
class TestRunner {
bool interactive;
bool testrecovery;
+ bool checkconsistency;
bool allow_pool_autoscaling;
bool allow_pool_balancer;