// vim: ts=8 sw=2 smarttab
#include "DataGenerator.h"
-#include "ObjectModel.h"
+#include <chrono>
+#include <iostream>
+#include <stdexcept>
+#include "ObjectModel.h"
#include "common/debug.h"
#include "common/dout.h"
-
#include "fmt/format.h"
#include "fmt/ranges.h"
-#include <chrono>
-#include <iostream>
-#include <stdexcept>
-
#define dout_subsys ceph_subsys_rados
#define dout_context g_ceph_context
using DataGenerator = ceph::io_exerciser::data_generation::DataGenerator;
-using SeededRandomGenerator = ceph::io_exerciser::data_generation
- ::SeededRandomGenerator;
-using HeaderedSeededRandomGenerator = ceph::io_exerciser::data_generation
- ::HeaderedSeededRandomGenerator;
+using SeededRandomGenerator =
+ ceph::io_exerciser::data_generation ::SeededRandomGenerator;
+using HeaderedSeededRandomGenerator =
+ ceph::io_exerciser::data_generation ::HeaderedSeededRandomGenerator;
std::unique_ptr<DataGenerator> DataGenerator::create_generator(
- GenerationType generationType, const ObjectModel& model)
-{
- switch(generationType)
- {
+ GenerationType generationType, const ObjectModel& model) {
+ switch (generationType) {
case GenerationType::SeededRandom:
return std::make_unique<SeededRandomGenerator>(model);
case GenerationType::HeaderedSeededRandom:
return nullptr;
}
-bufferlist DataGenerator::generate_wrong_data(uint64_t offset, uint64_t length)
-{
+bufferlist DataGenerator::generate_wrong_data(uint64_t offset,
+ uint64_t length) {
bufferlist retlist;
uint64_t block_size = m_model.get_block_size();
char buffer[block_size];
- for (uint64_t block_offset = offset;
- block_offset < offset + length;
- block_offset++)
- {
+ for (uint64_t block_offset = offset; block_offset < offset + length;
+ block_offset++) {
std::memset(buffer, 0, block_size);
retlist.append(ceph::bufferptr(buffer, block_size));
}
return retlist;
}
-bool DataGenerator::validate(bufferlist& bufferlist, uint64_t offset, uint64_t length)
-{
+bool DataGenerator::validate(bufferlist& bufferlist, uint64_t offset,
+ uint64_t length) {
return bufferlist.contents_equal(generate_data(offset, length));
}
-ceph::bufferptr SeededRandomGenerator::generate_block(uint64_t block_offset)
-{
+ceph::bufferptr SeededRandomGenerator::generate_block(uint64_t block_offset) {
uint64_t block_size = m_model.get_block_size();
char buffer[block_size];
constexpr size_t generation_length = sizeof(uint64_t);
- for (uint64_t i = 0; i < block_size; i+=(2*generation_length), rand1++, rand2--)
- {
+ for (uint64_t i = 0; i < block_size;
+ i += (2 * generation_length), rand1++, rand2--) {
std::memcpy(buffer + i, &rand1, generation_length);
std::memcpy(buffer + i + generation_length, &rand2, generation_length);
}
size_t remainingBytes = block_size % (generation_length * 2);
- if (remainingBytes > generation_length)
- {
+ if (remainingBytes > generation_length) {
size_t remainingBytes2 = remainingBytes - generation_length;
std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes);
std::memcpy(buffer + block_size - remainingBytes2, &rand2, remainingBytes2);
- }
- else if (remainingBytes > 0)
- {
+ } else if (remainingBytes > 0) {
std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes);
}
return ceph::bufferptr(buffer, block_size);
}
-ceph::bufferptr SeededRandomGenerator::generate_wrong_block(uint64_t block_offset)
-{
+ceph::bufferptr SeededRandomGenerator::generate_wrong_block(
+ uint64_t block_offset) {
uint64_t block_size = m_model.get_block_size();
char buffer[block_size];
constexpr size_t generation_length = sizeof(uint64_t);
- for (uint64_t i = 0; i < block_size; i+=(2*generation_length), rand1++, rand2--)
- {
+ for (uint64_t i = 0; i < block_size;
+ i += (2 * generation_length), rand1++, rand2--) {
std::memcpy(buffer + i, &rand1, generation_length);
std::memcpy(buffer + i + generation_length, &rand2, generation_length);
}
size_t remainingBytes = block_size % (generation_length * 2);
- if (remainingBytes > generation_length)
- {
+ if (remainingBytes > generation_length) {
size_t remainingBytes2 = remainingBytes - generation_length;
std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes);
std::memcpy(buffer + block_size - remainingBytes2, &rand2, remainingBytes2);
- }
- else if (remainingBytes > 0)
- {
+ } else if (remainingBytes > 0) {
std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes);
}
return ceph::bufferptr(buffer, block_size);
}
-bufferlist SeededRandomGenerator::generate_data(uint64_t offset, uint64_t length)
-{
+bufferlist SeededRandomGenerator::generate_data(uint64_t offset,
+ uint64_t length) {
bufferlist retlist;
- for (uint64_t block_offset = offset; block_offset < offset + length; block_offset++)
- {
+ for (uint64_t block_offset = offset; block_offset < offset + length;
+ block_offset++) {
retlist.append(generate_block(block_offset));
}
return retlist;
}
-bufferlist SeededRandomGenerator::generate_wrong_data(uint64_t offset, uint64_t length)
-{
+bufferlist SeededRandomGenerator::generate_wrong_data(uint64_t offset,
+ uint64_t length) {
bufferlist retlist;
- for (uint64_t block_offset = offset; block_offset < offset + length; block_offset++)
- {
+ for (uint64_t block_offset = offset; block_offset < offset + length;
+ block_offset++) {
retlist.append(generate_wrong_block(block_offset));
}
return retlist;
}
-HeaderedSeededRandomGenerator
- ::HeaderedSeededRandomGenerator(const ObjectModel& model,
- std::optional<uint64_t> unique_run_id) :
- SeededRandomGenerator(model),
- unique_run_id(unique_run_id.value_or(generate_unique_run_id()))
-{
-
-}
+HeaderedSeededRandomGenerator ::HeaderedSeededRandomGenerator(
+ const ObjectModel& model, std::optional<uint64_t> unique_run_id)
+ : SeededRandomGenerator(model),
+ unique_run_id(unique_run_id.value_or(generate_unique_run_id())) {}
-uint64_t HeaderedSeededRandomGenerator::generate_unique_run_id()
-{
+uint64_t HeaderedSeededRandomGenerator::generate_unique_run_id() {
std::mt19937_64 random_generator =
- std::mt19937_64(duration_cast<std::chrono::milliseconds>(
- std::chrono::system_clock::now().time_since_epoch()).count());
+ std::mt19937_64(duration_cast<std::chrono::milliseconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count());
- return random_generator();
+ return random_generator();
}
-ceph::bufferptr HeaderedSeededRandomGenerator::generate_block(uint64_t block_offset)
-{
+ceph::bufferptr HeaderedSeededRandomGenerator::generate_block(
+ uint64_t block_offset) {
SeedBytes seed = m_model.get_seed(block_offset);
- TimeBytes current_time = duration_cast<std::chrono::milliseconds>(
- std::chrono::system_clock::now().time_since_epoch()).count();
+ TimeBytes current_time =
+ duration_cast<std::chrono::milliseconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count();
- ceph::bufferptr bufferptr = SeededRandomGenerator::generate_block(block_offset);
+ ceph::bufferptr bufferptr =
+ SeededRandomGenerator::generate_block(block_offset);
- std::memcpy(bufferptr.c_str() + uniqueIdStart(), &unique_run_id, uniqueIdLength());
+ std::memcpy(bufferptr.c_str() + uniqueIdStart(), &unique_run_id,
+ uniqueIdLength());
std::memcpy(bufferptr.c_str() + seedStart(), &seed, seedLength());
std::memcpy(bufferptr.c_str() + timeStart(), ¤t_time, timeLength());
return bufferptr;
}
-ceph::bufferptr HeaderedSeededRandomGenerator::generate_wrong_block(uint64_t block_offset)
-{
+ceph::bufferptr HeaderedSeededRandomGenerator::generate_wrong_block(
+ uint64_t block_offset) {
return HeaderedSeededRandomGenerator::generate_block(block_offset % 8);
}
const HeaderedSeededRandomGenerator::UniqueIdBytes
- HeaderedSeededRandomGenerator::readUniqueRunId(uint64_t block_offset,
- const bufferlist& bufferlist)
-{
+HeaderedSeededRandomGenerator::readUniqueRunId(uint64_t block_offset,
+ const bufferlist& bufferlist) {
UniqueIdBytes read_unique_run_id = 0;
- std::memcpy(&read_unique_run_id,
- &bufferlist[(block_offset * m_model.get_block_size()) + uniqueIdStart()],
- uniqueIdLength());
+ std::memcpy(
+ &read_unique_run_id,
+ &bufferlist[(block_offset * m_model.get_block_size()) + uniqueIdStart()],
+ uniqueIdLength());
return read_unique_run_id;
}
const HeaderedSeededRandomGenerator::SeedBytes
- HeaderedSeededRandomGenerator::readSeed(uint64_t block_offset,
- const bufferlist& bufferlist)
-{
+HeaderedSeededRandomGenerator::readSeed(uint64_t block_offset,
+ const bufferlist& bufferlist) {
SeedBytes read_seed = 0;
- std::memcpy(&read_seed,
- &bufferlist[(block_offset * m_model.get_block_size()) + seedStart()],
- seedLength());
+ std::memcpy(
+ &read_seed,
+ &bufferlist[(block_offset * m_model.get_block_size()) + seedStart()],
+ seedLength());
return read_seed;
}
const HeaderedSeededRandomGenerator::TimeBytes
- HeaderedSeededRandomGenerator::readDateTime(uint64_t block_offset,
- const bufferlist& bufferlist)
-{
+HeaderedSeededRandomGenerator::readDateTime(uint64_t block_offset,
+ const bufferlist& bufferlist) {
TimeBytes read_time = 0;
- std::memcpy(&read_time,
- &bufferlist[(block_offset * m_model.get_block_size()) + timeStart()],
- timeLength());
+ std::memcpy(
+ &read_time,
+ &bufferlist[(block_offset * m_model.get_block_size()) + timeStart()],
+ timeLength());
return read_time;
}
bool HeaderedSeededRandomGenerator::validate(bufferlist& bufferlist,
- uint64_t offset, uint64_t length)
-{
+ uint64_t offset, uint64_t length) {
std::vector<uint64_t> invalid_block_offsets;
- for (uint64_t block_offset = offset; block_offset < offset + length; block_offset++)
- {
- bool valid_block
- = validate_block(block_offset,
- (bufferlist.c_str() + ((block_offset - offset) *
- m_model.get_block_size())));
- if (!valid_block)
- {
+ for (uint64_t block_offset = offset; block_offset < offset + length;
+ block_offset++) {
+ bool valid_block = validate_block(
+ block_offset, (bufferlist.c_str() +
+ ((block_offset - offset) * m_model.get_block_size())));
+ if (!valid_block) {
invalid_block_offsets.push_back(block_offset);
}
}
- if (!invalid_block_offsets.empty())
- {
+ if (!invalid_block_offsets.empty()) {
printDebugInformationForOffsets(offset, invalid_block_offsets, bufferlist);
}
}
bool HeaderedSeededRandomGenerator::validate_block(uint64_t block_offset,
- const char* buffer_start)
-{
+ const char* buffer_start) {
// We validate the block matches what we generate byte for byte
// however we ignore the time section of the header
ceph::bufferptr bufferptr = generate_block(block_offset);
bool valid = strncmp(bufferptr.c_str(), buffer_start, timeStart()) == 0;
- valid = valid ? strncmp(bufferptr.c_str() + timeEnd(),
- buffer_start + timeEnd(),
- m_model.get_block_size() - timeEnd()) == 0 : valid;
+ valid = valid
+ ? strncmp(bufferptr.c_str() + timeEnd(), buffer_start + timeEnd(),
+ m_model.get_block_size() - timeEnd()) == 0
+ : valid;
return valid;
}
const HeaderedSeededRandomGenerator::ErrorType
- HeaderedSeededRandomGenerator::getErrorTypeForBlock(uint64_t read_offset,
- uint64_t block_offset,
- const bufferlist& bufferlist)
-{
- try
- {
- UniqueIdBytes read_unique_run_id = readUniqueRunId(block_offset - read_offset,
- bufferlist);
- if (unique_run_id != read_unique_run_id)
- {
+HeaderedSeededRandomGenerator::getErrorTypeForBlock(
+ uint64_t read_offset, uint64_t block_offset, const bufferlist& bufferlist) {
+ try {
+ UniqueIdBytes read_unique_run_id =
+ readUniqueRunId(block_offset - read_offset, bufferlist);
+ if (unique_run_id != read_unique_run_id) {
return ErrorType::RUN_ID_MISMATCH;
}
SeedBytes read_seed = readSeed(block_offset - read_offset, bufferlist);
- if (m_model.get_seed(block_offset) != read_seed)
- {
+ if (m_model.get_seed(block_offset) != read_seed) {
return ErrorType::SEED_MISMATCH;
}
if (std::strncmp(&bufferlist[((block_offset - read_offset) *
- m_model.get_block_size()) + bodyStart()],
+ m_model.get_block_size()) +
+ bodyStart()],
generate_block(block_offset).c_str() + bodyStart(),
- m_model.get_block_size() - bodyStart()) != 0)
- {
+ m_model.get_block_size() - bodyStart()) != 0) {
return ErrorType::DATA_MISMATCH;
}
- }
- catch(const std::exception& e)
- {
+ } catch (const std::exception& e) {
return ErrorType::DATA_NOT_FOUND;
}
return ErrorType::UNKNOWN;
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationForBlock(uint64_t read_offset, uint64_t block_offset,
- const bufferlist& bufferlist)
-{
- ErrorType blockError = getErrorTypeForBlock(read_offset, block_offset, bufferlist);
+void HeaderedSeededRandomGenerator ::printDebugInformationForBlock(
+ uint64_t read_offset, uint64_t block_offset, const bufferlist& bufferlist) {
+ ErrorType blockError =
+ getErrorTypeForBlock(read_offset, block_offset, bufferlist);
TimeBytes read_time = 0;
std::time_t ttp;
char read_bytes[m_model.get_block_size()];
char generated_bytes[m_model.get_block_size()];
- if (blockError == ErrorType::DATA_MISMATCH || blockError == ErrorType::UNKNOWN)
- {
+ if (blockError == ErrorType::DATA_MISMATCH ||
+ blockError == ErrorType::UNKNOWN) {
read_time = readDateTime(block_offset - read_offset, bufferlist);
- std::chrono::system_clock::time_point time_point{std::chrono::milliseconds{read_time}};
+ std::chrono::system_clock::time_point time_point{
+ std::chrono::milliseconds{read_time}};
ttp = std::chrono::system_clock::to_time_t(time_point);
- std::memcpy(&read_bytes,
- &bufferlist[((block_offset - read_offset) * m_model.get_block_size())],
- m_model.get_block_size() - bodyStart());
- std::memcpy(&generated_bytes,
- generate_block(block_offset).c_str(),
+ std::memcpy(
+ &read_bytes,
+ &bufferlist[((block_offset - read_offset) * m_model.get_block_size())],
+ m_model.get_block_size() - bodyStart());
+ std::memcpy(&generated_bytes, generate_block(block_offset).c_str(),
m_model.get_block_size() - bodyStart());
}
std::string error_string;
- switch(blockError)
- {
- case ErrorType::RUN_ID_MISMATCH:
- {
- UniqueIdBytes read_unique_run_id = readUniqueRunId((block_offset - read_offset),
- bufferlist);
- error_string = fmt::format("Header (Run ID) mismatch detected at block {} "
- "(byte offset {}) Header expected run id {} but found id {}. "
- "Block data corrupt or not written from this instance of this application.",
- block_offset,
- block_offset * m_model.get_block_size(),
- unique_run_id,
- read_unique_run_id);
- }
- break;
-
- case ErrorType::SEED_MISMATCH:
- {
+ switch (blockError) {
+ case ErrorType::RUN_ID_MISMATCH: {
+ UniqueIdBytes read_unique_run_id =
+ readUniqueRunId((block_offset - read_offset), bufferlist);
+ error_string = fmt::format(
+ "Header (Run ID) mismatch detected at block {} "
+ "(byte offset {}) Header expected run id {} but found id {}. "
+ "Block data corrupt or not written from this instance of this "
+ "application.",
+ block_offset, block_offset * m_model.get_block_size(), unique_run_id,
+ read_unique_run_id);
+ } break;
+
+ case ErrorType::SEED_MISMATCH: {
SeedBytes read_seed = readSeed((block_offset - read_offset), bufferlist);
- if (m_model.get_seed_offsets(read_seed).size() == 0)
- {
- error_string = fmt::format("Data (Seed) mismatch detected at block {}"
- " (byte offset {}). Header expected seed {} but found seed {}. "
- "Read data was not from any other recognised block in the object.",
- block_offset,
- block_offset * m_model.get_block_size(),
- m_model.get_seed(block_offset),
- read_seed);
- }
- else
- {
+ if (m_model.get_seed_offsets(read_seed).size() == 0) {
+ error_string = fmt::format(
+ "Data (Seed) mismatch detected at block {}"
+ " (byte offset {}). Header expected seed {} but found seed {}. "
+ "Read data was not from any other recognised block in the object.",
+ block_offset, block_offset * m_model.get_block_size(),
+ m_model.get_seed(block_offset), read_seed);
+ } else {
std::vector<int> seed_offsets = m_model.get_seed_offsets(read_seed);
- error_string = fmt::format("Data (Seed) mismatch detected at block {}"
- " (byte offset {}). Header expected seed {} but found seed {}."
- " Read data was from a different block(s): {}",
- block_offset,
- block_offset * m_model.get_block_size(),
- m_model.get_seed(block_offset),
- read_seed,
+ error_string = fmt::format(
+ "Data (Seed) mismatch detected at block {}"
+ " (byte offset {}). Header expected seed {} but found seed {}."
+ " Read data was from a different block(s): {}",
+ block_offset, block_offset * m_model.get_block_size(),
+ m_model.get_seed(block_offset), read_seed,
fmt::join(seed_offsets.begin(), seed_offsets.end(), ""));
}
- }
- break;
-
- case ErrorType::DATA_MISMATCH:
- {
- error_string = fmt::format("Data (Body) mismatch detected at block {}"
- " (byte offset {}). Header data matches, data body does not."
- " Data written at {}\nExpected data: \n{:02x}\nRead data:{:02x}",
- block_offset,
- block_offset * m_model.get_block_size(),
+ } break;
+
+ case ErrorType::DATA_MISMATCH: {
+ error_string = fmt::format(
+ "Data (Body) mismatch detected at block {}"
+ " (byte offset {}). Header data matches, data body does not."
+ " Data written at {}\nExpected data: \n{:02x}\nRead data:{:02x}",
+ block_offset, block_offset * m_model.get_block_size(),
std::ctime(&ttp),
- fmt::join(generated_bytes, generated_bytes + m_model.get_block_size(), ""),
+ fmt::join(generated_bytes, generated_bytes + m_model.get_block_size(),
+ ""),
fmt::join(read_bytes, read_bytes + m_model.get_block_size(), ""));
- }
- break;
+ } break;
- case ErrorType::DATA_NOT_FOUND:
- {
+ case ErrorType::DATA_NOT_FOUND: {
uint64_t bufferlist_length = bufferlist.to_str().size();
- error_string = fmt::format("Data (Body) could not be read at block {}"
- " (byte offset {}) offset in bufferlist returned from read: {}"
- " ({} bytes). Returned bufferlist length: {}.",
- block_offset,
- block_offset * m_model.get_block_size(),
+ error_string = fmt::format(
+ "Data (Body) could not be read at block {}"
+ " (byte offset {}) offset in bufferlist returned from read: {}"
+ " ({} bytes). Returned bufferlist length: {}.",
+ block_offset, block_offset * m_model.get_block_size(),
(block_offset - read_offset),
(block_offset - read_offset) * m_model.get_block_size(),
bufferlist_length);
- }
- break;
+ } break;
case ErrorType::UNKNOWN:
- [[ fallthrough ]];
-
- default:
- {
- error_string = fmt::format("Data mismatch detected at block {}"
- " (byte offset {}).\nExpected data:\n{:02x}\nRead data:\n{:02x}",
- block_offset,
- block_offset * m_model.get_block_size(),
- fmt::join(generated_bytes, generated_bytes + m_model.get_block_size(), ""),
+ [[fallthrough]];
+
+ default: {
+ error_string = fmt::format(
+ "Data mismatch detected at block {}"
+ " (byte offset {}).\nExpected data:\n{:02x}\nRead data:\n{:02x}",
+ block_offset, block_offset * m_model.get_block_size(),
+ fmt::join(generated_bytes, generated_bytes + m_model.get_block_size(),
+ ""),
fmt::join(read_bytes, read_bytes + m_model.get_block_size(), ""));
- }
- break;
+ } break;
}
dout(0) << error_string << dendl;
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationForRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- ErrorType rangeError,
- const bufferlist& bufferlist)
-{
- switch(rangeError)
- {
- case ErrorType::RUN_ID_MISMATCH:
- printDebugInformationForRunIdMismatchRange(read_offset, start_block_offset,
- range_length_in_blocks, bufferlist);
- break;
- case ErrorType::SEED_MISMATCH:
- printDebugInformationForSeedMismatchRange(read_offset, start_block_offset,
- range_length_in_blocks, bufferlist);
- break;
- case ErrorType::DATA_MISMATCH:
- printDebugInformationDataBodyMismatchRange(read_offset, start_block_offset,
- range_length_in_blocks, bufferlist);
- break;
- case ErrorType::DATA_NOT_FOUND:
- printDebugInformationDataNotFoundRange(read_offset, start_block_offset,
- range_length_in_blocks, bufferlist);
- break;
- case ErrorType::UNKNOWN:
- [[ fallthrough ]];
- default:
- printDebugInformationCorruptRange(read_offset, start_block_offset,
- range_length_in_blocks, bufferlist);
- break;
+void HeaderedSeededRandomGenerator ::printDebugInformationForRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, ErrorType rangeError,
+ const bufferlist& bufferlist) {
+ switch (rangeError) {
+ case ErrorType::RUN_ID_MISMATCH:
+ printDebugInformationForRunIdMismatchRange(
+ read_offset, start_block_offset, range_length_in_blocks, bufferlist);
+ break;
+ case ErrorType::SEED_MISMATCH:
+ printDebugInformationForSeedMismatchRange(
+ read_offset, start_block_offset, range_length_in_blocks, bufferlist);
+ break;
+ case ErrorType::DATA_MISMATCH:
+ printDebugInformationDataBodyMismatchRange(
+ read_offset, start_block_offset, range_length_in_blocks, bufferlist);
+ break;
+ case ErrorType::DATA_NOT_FOUND:
+ printDebugInformationDataNotFoundRange(
+ read_offset, start_block_offset, range_length_in_blocks, bufferlist);
+ break;
+ case ErrorType::UNKNOWN:
+ [[fallthrough]];
+ default:
+ printDebugInformationCorruptRange(read_offset, start_block_offset,
+ range_length_in_blocks, bufferlist);
+ break;
}
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationForRunIdMismatchRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist)
-{
+void HeaderedSeededRandomGenerator ::printDebugInformationForRunIdMismatchRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist) {
uint64_t range_start = start_block_offset;
uint64_t range_length = 0;
- UniqueIdBytes initial_read_unique_run_id = readUniqueRunId(start_block_offset - read_offset,
- bufferlist);
+ UniqueIdBytes initial_read_unique_run_id =
+ readUniqueRunId(start_block_offset - read_offset, bufferlist);
for (uint64_t i = start_block_offset;
- i < start_block_offset + range_length_in_blocks; i++)
- {
- ceph_assert(getErrorTypeForBlock(read_offset, i, bufferlist)
- == ErrorType::RUN_ID_MISMATCH);
+ i < start_block_offset + range_length_in_blocks; i++) {
+ ceph_assert(getErrorTypeForBlock(read_offset, i, bufferlist) ==
+ ErrorType::RUN_ID_MISMATCH);
- UniqueIdBytes read_unique_run_id = readUniqueRunId(i - read_offset, bufferlist);
+ UniqueIdBytes read_unique_run_id =
+ readUniqueRunId(i - read_offset, bufferlist);
if (initial_read_unique_run_id != read_unique_run_id ||
- i == (start_block_offset + range_length_in_blocks - 1))
- {
- if (range_length == 1)
- {
+ i == (start_block_offset + range_length_in_blocks - 1)) {
+ if (range_length == 1) {
printDebugInformationForBlock(read_offset, i, bufferlist);
- }
- else if (range_length > 1)
- {
- dout(0) << fmt::format("Data (Run ID) Mismatch detected from block {} ({} bytes)"
- " and spanning a range of {} blocks ({} bytes). "
- "Expected run id {} for range but found id {}"
- " for all blocks in range. "
- "Block data corrupt or not written from this instance of this application.",
- range_start,
- range_start * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size(),
- unique_run_id,
- initial_read_unique_run_id) << dendl;
+ } else if (range_length > 1) {
+ dout(0)
+ << fmt::format(
+ "Data (Run ID) Mismatch detected from block {} ({} bytes)"
+ " and spanning a range of {} blocks ({} bytes). "
+ "Expected run id {} for range but found id {}"
+ " for all blocks in range. "
+ "Block data corrupt or not written from this instance of "
+ "this application.",
+ range_start, range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ unique_run_id, initial_read_unique_run_id)
+ << dendl;
}
range_start = i;
range_length = 1;
initial_read_unique_run_id = read_unique_run_id;
- }
- else
- {
+ } else {
range_length++;
}
}
- if (range_length == 1)
- {
- printDebugInformationForBlock(read_offset,
- start_block_offset + range_length_in_blocks - 1,
- bufferlist);
- }
- else if (range_length > 1)
- {
- dout(0) << fmt::format("Data (Run ID) Mismatch detected from block {}"
- " ({} bytes) and spanning a range of {} blocks ({} bytes). "
- "Expected run id {} for range but found id for all blocks in range. "
- "Block data corrupt or not written from this instance of this application.",
- range_start,
- range_start * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size(),
- unique_run_id,
- initial_read_unique_run_id)
+ if (range_length == 1) {
+ printDebugInformationForBlock(
+ read_offset, start_block_offset + range_length_in_blocks - 1,
+ bufferlist);
+ } else if (range_length > 1) {
+ dout(0) << fmt::format(
+ "Data (Run ID) Mismatch detected from block {}"
+ " ({} bytes) and spanning a range of {} blocks ({} bytes). "
+ "Expected run id {} for range but found id for all blocks "
+ "in range. "
+ "Block data corrupt or not written from this instance of "
+ "this application.",
+ range_start, range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ unique_run_id, initial_read_unique_run_id)
<< dendl;
}
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationForSeedMismatchRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist)
-{
+void HeaderedSeededRandomGenerator ::printDebugInformationForSeedMismatchRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist) {
uint64_t range_start = start_block_offset;
uint64_t range_length = 0;
// Assert here if needed, as we can't support values
// that can't be converted to a signed integer.
- ceph_assert(m_model.get_block_size() < (std::numeric_limits<uint64_t>::max() / 2));
+ ceph_assert(m_model.get_block_size() <
+ (std::numeric_limits<uint64_t>::max() / 2));
std::optional<int64_t> range_offset = 0;
for (uint64_t i = start_block_offset;
- i < start_block_offset + range_length_in_blocks; i++)
- {
- ceph_assert(getErrorTypeForBlock(read_offset, i, bufferlist)
- == ErrorType::SEED_MISMATCH);
+ i < start_block_offset + range_length_in_blocks; i++) {
+ ceph_assert(getErrorTypeForBlock(read_offset, i, bufferlist) ==
+ ErrorType::SEED_MISMATCH);
SeedBytes read_seed = readSeed(i - read_offset, bufferlist);
std::vector<int> seed_found_offsets = m_model.get_seed_offsets(read_seed);
if ((seed_found_offsets.size() == 1 &&
- (static_cast<int64_t>(seed_found_offsets.front() - i) == range_offset)) ||
- range_length == 0)
- {
- if (range_length == 0)
- {
+ (static_cast<int64_t>(seed_found_offsets.front() - i) ==
+ range_offset)) ||
+ range_length == 0) {
+ if (range_length == 0) {
range_start = i;
- if (seed_found_offsets.size() > 0)
- {
+ if (seed_found_offsets.size() > 0) {
range_offset = seed_found_offsets.front() - i;
- }
- else
- {
+ } else {
range_offset = std::nullopt;
}
}
range_length++;
- }
- else
- {
- if (range_length == 1)
- {
+ } else {
+ if (range_length == 1) {
printDebugInformationForBlock(read_offset, i - 1, bufferlist);
- }
- else if (range_length > 1 && range_offset.has_value())
- {
- dout(0) << fmt::format("Data (Seed) Mismatch detected from block {}"
- " ({} bytes) and spanning a range of {} blocks ({} bytes). "
- "Returned data located starting from block {} ({} bytes) "
- "and spanning a range of {} blocks ({} bytes).",
- range_start,
- range_start * m_model.get_block_size(),
- range_length, range_length * m_model.get_block_size(),
- static_cast<uint64_t>(*range_offset) + range_start,
- (static_cast<uint64_t>(*range_offset) + range_start)
- * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size())
- << dendl;
- }
- else
- {
- dout(0) << fmt::format("Data (Seed) Mismatch detected from block {}"
- " ({} bytes) and spanning a range of {} blocks ({} bytes). "
- "Data seed mismatch spanning a range of {} blocks ({} bytes).",
- range_start,
- range_start * m_model.get_block_size(),
- range_length, range_length * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size())
- << dendl;
+ } else if (range_length > 1 && range_offset.has_value()) {
+ dout(0)
+ << fmt::format(
+ "Data (Seed) Mismatch detected from block {}"
+ " ({} bytes) and spanning a range of {} blocks ({} bytes). "
+ "Returned data located starting from block {} ({} bytes) "
+ "and spanning a range of {} blocks ({} bytes).",
+ range_start, range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ static_cast<uint64_t>(*range_offset) + range_start,
+ (static_cast<uint64_t>(*range_offset) + range_start) *
+ m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size())
+ << dendl;
+ } else {
+ dout(0)
+ << fmt::format(
+ "Data (Seed) Mismatch detected from block {}"
+ " ({} bytes) and spanning a range of {} blocks ({} bytes). "
+ "Data seed mismatch spanning a range of {} blocks ({} "
+ "bytes).",
+ range_start, range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size())
+ << dendl;
}
range_length = 1;
range_start = i;
- if (seed_found_offsets.size() > 0)
- {
+ if (seed_found_offsets.size() > 0) {
range_offset = seed_found_offsets.front() - i;
- }
- else
- {
+ } else {
range_offset = std::nullopt;
}
}
}
- if (range_length == 1)
- {
- printDebugInformationForBlock(read_offset,
- start_block_offset + range_length_in_blocks - 1,
- bufferlist);
- }
- else if (range_length > 1 && range_offset.has_value())
- {
- dout(0) << fmt::format("Data (Seed) Mismatch detected from block {} ({} bytes) "
- "and spanning a range of {} blocks ({} bytes). "
- "Returned data located starting from block {} ({} bytes) "
- "and spanning a range of {} blocks ({} bytes).",
- range_start,
- range_start * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size(),
- *range_offset + range_start,
- (*range_offset + range_start) * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size())
+ if (range_length == 1) {
+ printDebugInformationForBlock(
+ read_offset, start_block_offset + range_length_in_blocks - 1,
+ bufferlist);
+ } else if (range_length > 1 && range_offset.has_value()) {
+ dout(0) << fmt::format(
+ "Data (Seed) Mismatch detected from block {} ({} bytes) "
+ "and spanning a range of {} blocks ({} bytes). "
+ "Returned data located starting from block {} ({} bytes) "
+ "and spanning a range of {} blocks ({} bytes).",
+ range_start, range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ *range_offset + range_start,
+ (*range_offset + range_start) * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size())
<< dendl;
- }
- else
- {
- dout(0) << fmt::format("Data (Seed) Mismatch detected from block {} ({} bytes) "
- "and spanning a range of {} blocks ({} bytes). "
- "and spanning a range of {} blocks ({} bytes).",
- range_start,
- range_start * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size(),
- range_length,
- range_length * m_model.get_block_size())
+ } else {
+ dout(0) << fmt::format(
+ "Data (Seed) Mismatch detected from block {} ({} bytes) "
+ "and spanning a range of {} blocks ({} bytes). "
+ "and spanning a range of {} blocks ({} bytes).",
+ range_start, range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size())
<< dendl;
}
}
-void HeaderedSeededRandomGenerator
-::printDebugInformationDataBodyMismatchRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist)
-{
- dout(0) << fmt::format("Data Mismatch detected in blocks from {} to {}. "
- "Headers look as expected for range, "
- "but generated data body does not match. "
- "More information given for individual blocks below.",
- start_block_offset,
- start_block_offset + range_length_in_blocks - 1)
+void HeaderedSeededRandomGenerator ::printDebugInformationDataBodyMismatchRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist) {
+ dout(0) << fmt::format(
+ "Data Mismatch detected in blocks from {} to {}. "
+ "Headers look as expected for range, "
+ "but generated data body does not match. "
+ "More information given for individual blocks below.",
+ start_block_offset,
+ start_block_offset + range_length_in_blocks - 1)
<< dendl;
for (uint64_t i = start_block_offset;
- i < start_block_offset + range_length_in_blocks; i++)
- {
+ i < start_block_offset + range_length_in_blocks; i++) {
printDebugInformationForBlock(read_offset, i, bufferlist);
}
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationCorruptRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist)
-{
- dout(0) << fmt::format("Data Mismatch detected in blocks from {} to {}. "
- "Headers look as expected for range, "
- "but generated data body does not match. "
- "More information given for individual blocks below.",
- start_block_offset,
- start_block_offset + range_length_in_blocks - 1)
+void HeaderedSeededRandomGenerator ::printDebugInformationCorruptRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist) {
+ dout(0) << fmt::format(
+ "Data Mismatch detected in blocks from {} to {}. "
+ "Headers look as expected for range, "
+ "but generated data body does not match. "
+ "More information given for individual blocks below.",
+ start_block_offset,
+ start_block_offset + range_length_in_blocks - 1)
<< dendl;
for (uint64_t i = start_block_offset;
- i < start_block_offset + range_length_in_blocks; i++)
- {
+ i < start_block_offset + range_length_in_blocks; i++) {
printDebugInformationForBlock(read_offset, i, bufferlist);
}
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationDataNotFoundRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist)
-{
- dout(0) << fmt::format("Data not found for blocks from {} to {}. "
- "More information given for individual blocks below.",
- start_block_offset,
- start_block_offset + range_length_in_blocks - 1)
+void HeaderedSeededRandomGenerator ::printDebugInformationDataNotFoundRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist) {
+ dout(0) << fmt::format(
+ "Data not found for blocks from {} to {}. "
+ "More information given for individual blocks below.",
+ start_block_offset,
+ start_block_offset + range_length_in_blocks - 1)
<< dendl;
- for (uint64_t i = start_block_offset; i < start_block_offset + range_length_in_blocks; i++)
- {
+ for (uint64_t i = start_block_offset;
+ i < start_block_offset + range_length_in_blocks; i++) {
printDebugInformationForBlock(read_offset, i, bufferlist);
}
}
-void HeaderedSeededRandomGenerator
- ::printDebugInformationForOffsets(uint64_t read_offset,
- std::vector<uint64_t> offsets,
- const bufferlist& bufferlist)
-{
+void HeaderedSeededRandomGenerator ::printDebugInformationForOffsets(
+ uint64_t read_offset, std::vector<uint64_t> offsets,
+ const bufferlist& bufferlist) {
uint64_t range_start = 0;
uint64_t range_length = 0;
ErrorType rangeError = ErrorType::UNKNOWN;
- for (const uint64_t& block_offset : offsets)
- {
- ErrorType blockError = getErrorTypeForBlock(read_offset, block_offset,
- bufferlist);
+ for (const uint64_t& block_offset : offsets) {
+ ErrorType blockError =
+ getErrorTypeForBlock(read_offset, block_offset, bufferlist);
- if (range_start == 0 && range_length == 0)
- {
+ if (range_start == 0 && range_length == 0) {
range_start = block_offset;
range_length = 1;
rangeError = blockError;
- }
- else if (blockError == rangeError &&
- range_start + range_length == block_offset)
-{
+ } else if (blockError == rangeError &&
+ range_start + range_length == block_offset) {
range_length++;
- }
- else
- {
- if (range_length == 1)
- {
+ } else {
+ if (range_length == 1) {
printDebugInformationForBlock(read_offset, range_start, bufferlist);
- }
- else if (range_length > 1)
- {
+ } else if (range_length > 1) {
printDebugInformationForRange(read_offset, range_start, range_length,
rangeError, bufferlist);
}
}
}
- if (range_length == 1)
- {
+ if (range_length == 1) {
printDebugInformationForBlock(read_offset, range_start, bufferlist);
- }
- else if (range_length > 1)
- {
+ } else if (range_length > 1) {
printDebugInformationForRange(read_offset, range_start, range_length,
rangeError, bufferlist);
}
#include <memory>
#include <random>
-#include "include/buffer.h"
#include "ObjectModel.h"
+#include "include/buffer.h"
/* Overview
*
*
* class HeaderedSeededRandomGenerator
* Inherits from SeededDataGenerator. Generates entirely random patterns
- * based on the seed retrieved by the model, however also appends a
+ * based on the seed retrieved by the model, however also appends a
* header to the start of each block. This generator also provides
* a range of verbose debug options to help disagnose a miscompare
* whenever it detects unexpected data.
*/
namespace ceph {
- namespace io_exerciser {
- namespace data_generation {
- enum class GenerationType {
- SeededRandom,
- HeaderedSeededRandom
- // CompressedGenerator
- // MixedGenerator
- };
-
- class DataGenerator {
- public:
- virtual ~DataGenerator() = default;
- static std::unique_ptr<DataGenerator>
- create_generator(GenerationType generatorType,
- const ObjectModel& model);
- virtual bufferlist generate_data(uint64_t length, uint64_t offset)=0;
- virtual bool validate(bufferlist& bufferlist, uint64_t offset,
- uint64_t length);
-
- // Used for testing debug outputs from data generation
- virtual bufferlist generate_wrong_data(uint64_t offset, uint64_t length);
-
- protected:
- const ObjectModel& m_model;
-
- DataGenerator(const ObjectModel& model) : m_model(model) {}
- };
-
- class SeededRandomGenerator : public DataGenerator
- {
- public:
- SeededRandomGenerator(const ObjectModel& model)
- : DataGenerator(model) {}
-
- virtual bufferptr generate_block(uint64_t offset);
- virtual bufferlist generate_data(uint64_t length, uint64_t offset) override;
- virtual bufferptr generate_wrong_block(uint64_t offset);
- virtual bufferlist generate_wrong_data(uint64_t offset, uint64_t length) override;
- };
-
- class HeaderedSeededRandomGenerator : public SeededRandomGenerator
- {
- public:
- HeaderedSeededRandomGenerator(const ObjectModel& model,
- std::optional<uint64_t> unique_run_id = std::nullopt);
-
- bufferptr generate_block(uint64_t offset) override;
- bufferptr generate_wrong_block(uint64_t offset) override;
- bool validate(bufferlist& bufferlist, uint64_t offset,
- uint64_t length) override;
-
- private:
- using UniqueIdBytes = uint64_t;
- using SeedBytes = int;
- using TimeBytes = uint64_t;
-
- enum class ErrorType {
- RUN_ID_MISMATCH,
- SEED_MISMATCH,
- DATA_MISMATCH,
- DATA_NOT_FOUND,
- UNKNOWN
- };
-
- constexpr uint8_t headerStart() const
- { return 0; };
- constexpr uint8_t uniqueIdStart() const
- { return headerStart(); };
- constexpr uint8_t uniqueIdLength() const
- { return sizeof(UniqueIdBytes); };
- constexpr uint8_t seedStart() const
- { return uniqueIdStart() + uniqueIdLength(); };
- constexpr uint8_t seedLength() const
- { return sizeof(SeedBytes); };
- constexpr uint8_t timeStart() const
- { return seedStart() + seedLength(); };
- constexpr uint8_t timeLength() const
- { return sizeof(TimeBytes); };
- constexpr uint8_t timeEnd() const
- { return timeStart() + timeLength(); };
- constexpr uint8_t headerLength() const
- { return uniqueIdLength() + seedLength() + timeLength(); };
- constexpr uint8_t bodyStart() const
- { return headerStart() + headerLength(); };
-
- const UniqueIdBytes readUniqueRunId(uint64_t block_offset,
- const bufferlist& bufferlist);
- const SeedBytes readSeed(uint64_t block_offset,
- const bufferlist& bufferlist);
- const TimeBytes readDateTime(uint64_t block_offset,
+namespace io_exerciser {
+namespace data_generation {
+enum class GenerationType {
+ SeededRandom,
+ HeaderedSeededRandom
+ // CompressedGenerator
+ // MixedGenerator
+};
+
+class DataGenerator {
+ public:
+ virtual ~DataGenerator() = default;
+ static std::unique_ptr<DataGenerator> create_generator(
+ GenerationType generatorType, const ObjectModel& model);
+ virtual bufferlist generate_data(uint64_t length, uint64_t offset) = 0;
+ virtual bool validate(bufferlist& bufferlist, uint64_t offset,
+ uint64_t length);
+
+ // Used for testing debug outputs from data generation
+ virtual bufferlist generate_wrong_data(uint64_t offset, uint64_t length);
+
+ protected:
+ const ObjectModel& m_model;
+
+ DataGenerator(const ObjectModel& model) : m_model(model) {}
+};
+
+class SeededRandomGenerator : public DataGenerator {
+ public:
+ SeededRandomGenerator(const ObjectModel& model) : DataGenerator(model) {}
+
+ virtual bufferptr generate_block(uint64_t offset);
+ virtual bufferlist generate_data(uint64_t length, uint64_t offset) override;
+ virtual bufferptr generate_wrong_block(uint64_t offset);
+ virtual bufferlist generate_wrong_data(uint64_t offset,
+ uint64_t length) override;
+};
+
+class HeaderedSeededRandomGenerator : public SeededRandomGenerator {
+ public:
+ HeaderedSeededRandomGenerator(
+ const ObjectModel& model,
+ std::optional<uint64_t> unique_run_id = std::nullopt);
+
+ bufferptr generate_block(uint64_t offset) override;
+ bufferptr generate_wrong_block(uint64_t offset) override;
+ bool validate(bufferlist& bufferlist, uint64_t offset,
+ uint64_t length) override;
+
+ private:
+ using UniqueIdBytes = uint64_t;
+ using SeedBytes = int;
+ using TimeBytes = uint64_t;
+
+ enum class ErrorType {
+ RUN_ID_MISMATCH,
+ SEED_MISMATCH,
+ DATA_MISMATCH,
+ DATA_NOT_FOUND,
+ UNKNOWN
+ };
+
+ constexpr uint8_t headerStart() const { return 0; };
+ constexpr uint8_t uniqueIdStart() const { return headerStart(); };
+ constexpr uint8_t uniqueIdLength() const { return sizeof(UniqueIdBytes); };
+ constexpr uint8_t seedStart() const {
+ return uniqueIdStart() + uniqueIdLength();
+ };
+ constexpr uint8_t seedLength() const { return sizeof(SeedBytes); };
+ constexpr uint8_t timeStart() const { return seedStart() + seedLength(); };
+ constexpr uint8_t timeLength() const { return sizeof(TimeBytes); };
+ constexpr uint8_t timeEnd() const { return timeStart() + timeLength(); };
+ constexpr uint8_t headerLength() const {
+ return uniqueIdLength() + seedLength() + timeLength();
+ };
+ constexpr uint8_t bodyStart() const {
+ return headerStart() + headerLength();
+ };
+
+ const UniqueIdBytes readUniqueRunId(uint64_t block_offset,
+ const bufferlist& bufferlist);
+ const SeedBytes readSeed(uint64_t block_offset, const bufferlist& bufferlist);
+ const TimeBytes readDateTime(uint64_t block_offset,
+ const bufferlist& bufferlist);
+
+ const UniqueIdBytes unique_run_id;
+
+ uint64_t generate_unique_run_id();
+
+ bool validate_block(uint64_t block_offset, const char* buffer_start);
+
+ const ErrorType getErrorTypeForBlock(uint64_t read_offset,
+ uint64_t block_offset,
const bufferlist& bufferlist);
- const UniqueIdBytes unique_run_id;
-
- uint64_t generate_unique_run_id();
-
- bool validate_block(uint64_t block_offset, const char* buffer_start);
-
- const ErrorType getErrorTypeForBlock(uint64_t read_offset,
- uint64_t block_offset,
- const bufferlist& bufferlist);
-
- void printDebugInformationForBlock(uint64_t read_offset,
- uint64_t block_offset,
- const bufferlist& bufferlist);
- void printDebugInformationForRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- ErrorType rangeError,
- const bufferlist& bufferlist);
-
- void printDebugInformationForRunIdMismatchRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist);
- void printDebugInformationForSeedMismatchRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist);
- void printDebugInformationDataBodyMismatchRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist);
- void printDebugInformationDataNotFoundRange(uint64_t ßread_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist);
- void printDebugInformationCorruptRange(uint64_t read_offset,
- uint64_t start_block_offset,
- uint64_t range_length_in_blocks,
- const bufferlist& bufferlist);
-
- void printDebugInformationForOffsets(uint64_t read_offset,
- std::vector<uint64_t> offsets,
- const bufferlist& bufferlist);
- };
- }
- }
-}
+ void printDebugInformationForBlock(uint64_t read_offset,
+ uint64_t block_offset,
+ const bufferlist& bufferlist);
+ void printDebugInformationForRange(uint64_t read_offset,
+ uint64_t start_block_offset,
+ uint64_t range_length_in_blocks,
+ ErrorType rangeError,
+ const bufferlist& bufferlist);
+
+ void printDebugInformationForRunIdMismatchRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist);
+ void printDebugInformationForSeedMismatchRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist);
+ void printDebugInformationDataBodyMismatchRange(
+ uint64_t read_offset, uint64_t start_block_offset,
+ uint64_t range_length_in_blocks, const bufferlist& bufferlist);
+ void printDebugInformationDataNotFoundRange(uint64_t ßread_offset,
+ uint64_t start_block_offset,
+ uint64_t range_length_in_blocks,
+ const bufferlist& bufferlist);
+ void printDebugInformationCorruptRange(uint64_t read_offset,
+ uint64_t start_block_offset,
+ uint64_t range_length_in_blocks,
+ const bufferlist& bufferlist);
+
+ void printDebugInformationForOffsets(uint64_t read_offset,
+ std::vector<uint64_t> offsets,
+ const bufferlist& bufferlist);
+};
+} // namespace data_generation
+} // namespace io_exerciser
+} // namespace ceph
using EcIoSequence = ceph::io_exerciser::EcIoSequence;
using ReadInjectSequence = ceph::io_exerciser::ReadInjectSequence;
-bool EcIoSequence::is_supported(Sequence sequence) const
-{
- return true;
-}
+bool EcIoSequence::is_supported(Sequence sequence) const { return true; }
-std::unique_ptr<IoSequence> EcIoSequence::generate_sequence(Sequence sequence,
- std::pair<int,int> obj_size_range,
- int k,
- int m,
- int seed)
-{
- switch(sequence)
- {
+std::unique_ptr<IoSequence> EcIoSequence::generate_sequence(
+ Sequence sequence, std::pair<int, int> obj_size_range, int k, int m,
+ int seed) {
+ switch (sequence) {
case Sequence::SEQUENCE_SEQ0:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ1:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ2:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ3:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ4:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ5:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ6:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ7:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ8:
- [[ fallthrough ]];
+ [[fallthrough]];
case Sequence::SEQUENCE_SEQ9:
return std::make_unique<ReadInjectSequence>(obj_size_range, seed,
sequence, k, m);
}
}
-EcIoSequence::EcIoSequence(std::pair<int,int> obj_size_range, int seed) :
- IoSequence(obj_size_range, seed),
- setup_inject(false), clear_inject(false), shard_to_inject(std::nullopt)
-{
-
-}
+EcIoSequence::EcIoSequence(std::pair<int, int> obj_size_range, int seed)
+ : IoSequence(obj_size_range, seed),
+ setup_inject(false),
+ clear_inject(false),
+ shard_to_inject(std::nullopt) {}
-void EcIoSequence::select_random_data_shard_to_inject_read_error(int k, int m)
-{
+void EcIoSequence::select_random_data_shard_to_inject_read_error(int k, int m) {
shard_to_inject = rng(k - 1);
setup_inject = true;
}
-void EcIoSequence::select_random_data_shard_to_inject_write_error(int k, int m)
-{
+void EcIoSequence::select_random_data_shard_to_inject_write_error(int k,
+ int m) {
// Write errors do not support injecting to the primary OSD
shard_to_inject = rng(1, k - 1);
setup_inject = true;
}
-void EcIoSequence::select_random_shard_to_inject_read_error(int k, int m)
-{
+void EcIoSequence::select_random_shard_to_inject_read_error(int k, int m) {
shard_to_inject = rng(k + m - 1);
setup_inject = true;
}
-void EcIoSequence::select_random_shard_to_inject_write_error(int k, int m)
-{
+void EcIoSequence::select_random_shard_to_inject_write_error(int k, int m) {
// Write errors do not support injecting to the primary OSD
shard_to_inject = rng(1, k + m - 1);
setup_inject = true;
}
-void EcIoSequence::generate_random_read_inject_type()
-{
- inject_op_type = static_cast<InjectOpType>(rng(static_cast<int>(InjectOpType::ReadEIO),
- static_cast<int>(InjectOpType::ReadMissingShard)));
+void EcIoSequence::generate_random_read_inject_type() {
+ inject_op_type = static_cast<InjectOpType>(
+ rng(static_cast<int>(InjectOpType::ReadEIO),
+ static_cast<int>(InjectOpType::ReadMissingShard)));
}
-void EcIoSequence::generate_random_write_inject_type()
-{
- inject_op_type = static_cast<InjectOpType>(rng(static_cast<int>(InjectOpType::WriteFailAndRollback),
- static_cast<int>(InjectOpType::WriteOSDAbort)));
+void EcIoSequence::generate_random_write_inject_type() {
+ inject_op_type = static_cast<InjectOpType>(
+ rng(static_cast<int>(InjectOpType::WriteFailAndRollback),
+ static_cast<int>(InjectOpType::WriteOSDAbort)));
}
-ceph::io_exerciser::ReadInjectSequence::ReadInjectSequence(std::pair<int,int> obj_size_range,
- int seed,
- Sequence s,
- int k, int m) :
- EcIoSequence(obj_size_range, seed)
-{
+ceph::io_exerciser::ReadInjectSequence::ReadInjectSequence(
+ std::pair<int, int> obj_size_range, int seed, Sequence s, int k, int m)
+ : EcIoSequence(obj_size_range, seed) {
child_sequence = IoSequence::generate_sequence(s, obj_size_range, seed);
select_random_data_shard_to_inject_read_error(k, m);
generate_random_read_inject_type();
}
-Sequence ceph::io_exerciser::ReadInjectSequence::get_id() const
-{
+Sequence ceph::io_exerciser::ReadInjectSequence::get_id() const {
return child_sequence->get_id();
}
-std::string ceph::io_exerciser::ReadInjectSequence::get_name() const
-{
+std::string ceph::io_exerciser::ReadInjectSequence::get_name() const {
return child_sequence->get_name() +
- " running with read errors injected on shard "
- + std::to_string(*shard_to_inject);
+ " running with read errors injected on shard " +
+ std::to_string(*shard_to_inject);
}
-std::unique_ptr<IoOp> ReadInjectSequence::next()
-{
+std::unique_ptr<IoOp> ReadInjectSequence::next() {
step++;
- if (nextOp)
- {
+ if (nextOp) {
std::unique_ptr<IoOp> retOp = nullptr;
nextOp.swap(retOp);
return retOp;
std::unique_ptr<IoOp> childOp = child_sequence->next();
- switch(childOp->getOpType())
- {
+ switch (childOp->getOpType()) {
case OpType::Remove:
nextOp.swap(childOp);
- switch(inject_op_type)
- {
- case InjectOpType::ReadEIO:
- return ClearReadErrorInjectOp::generate(*shard_to_inject, 0);
- case InjectOpType::ReadMissingShard:
- return ClearReadErrorInjectOp::generate(*shard_to_inject, 1);
- case InjectOpType::WriteFailAndRollback:
- return ClearWriteErrorInjectOp::generate(*shard_to_inject, 0);
- case InjectOpType::WriteOSDAbort:
- return ClearWriteErrorInjectOp::generate(*shard_to_inject, 3);
- case InjectOpType::None:
- [[ fallthrough ]];
- default:
- ceph_abort_msg("Unsupported operation");
- }
+ switch (inject_op_type) {
+ case InjectOpType::ReadEIO:
+ return ClearReadErrorInjectOp::generate(*shard_to_inject, 0);
+ case InjectOpType::ReadMissingShard:
+ return ClearReadErrorInjectOp::generate(*shard_to_inject, 1);
+ case InjectOpType::WriteFailAndRollback:
+ return ClearWriteErrorInjectOp::generate(*shard_to_inject, 0);
+ case InjectOpType::WriteOSDAbort:
+ return ClearWriteErrorInjectOp::generate(*shard_to_inject, 3);
+ case InjectOpType::None:
+ [[fallthrough]];
+ default:
+ ceph_abort_msg("Unsupported operation");
+ }
break;
case OpType::Create:
- switch(inject_op_type)
- {
+ switch (inject_op_type) {
case InjectOpType::ReadEIO:
- nextOp = InjectReadErrorOp::generate(*shard_to_inject, 0, 0, std::numeric_limits<uint64_t>::max());
+ nextOp = InjectReadErrorOp::generate(
+ *shard_to_inject, 0, 0, std::numeric_limits<uint64_t>::max());
break;
case InjectOpType::ReadMissingShard:
- nextOp = InjectReadErrorOp::generate(*shard_to_inject, 1, 0, std::numeric_limits<uint64_t>::max());
+ nextOp = InjectReadErrorOp::generate(
+ *shard_to_inject, 1, 0, std::numeric_limits<uint64_t>::max());
break;
case InjectOpType::WriteFailAndRollback:
- nextOp = InjectWriteErrorOp::generate(*shard_to_inject, 0, 0, std::numeric_limits<uint64_t>::max());
+ nextOp = InjectWriteErrorOp::generate(
+ *shard_to_inject, 0, 0, std::numeric_limits<uint64_t>::max());
break;
case InjectOpType::WriteOSDAbort:
- nextOp = InjectWriteErrorOp::generate(*shard_to_inject, 3, 0, std::numeric_limits<uint64_t>::max());
+ nextOp = InjectWriteErrorOp::generate(
+ *shard_to_inject, 3, 0, std::numeric_limits<uint64_t>::max());
break;
case InjectOpType::None:
- [[ fallthrough ]];
+ [[fallthrough]];
default:
ceph_abort_msg("Unsupported operation");
}
- break;
+ break;
default:
// Do nothing in default case
break;
return childOp;
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::ReadInjectSequence::_next()
-{
- ceph_abort_msg("Should not reach this point, "
- "this sequence should only consume complete sequences");
+std::unique_ptr<ceph::io_exerciser::IoOp>
+ceph::io_exerciser::ReadInjectSequence::_next() {
+ ceph_abort_msg(
+ "Should not reach this point, "
+ "this sequence should only consume complete sequences");
return DoneOp::generate();
}
-
-
-ceph::io_exerciser::Seq10::Seq10(std::pair<int,int> obj_size_range, int seed,
- int k, int m) :
- EcIoSequence(obj_size_range, seed), offset(0), length(1),
- failed_write_done(false), read_done(false), successful_write_done(false),
- test_all_lengths(false), // Only test length(1) due to time constraints
- test_all_sizes(false) // Only test obj_size(rand()) due to time constraints
+ceph::io_exerciser::Seq10::Seq10(std::pair<int, int> obj_size_range, int seed,
+ int k, int m)
+ : EcIoSequence(obj_size_range, seed),
+ offset(0),
+ length(1),
+ failed_write_done(false),
+ read_done(false),
+ successful_write_done(false),
+ test_all_lengths(false), // Only test length(1) due to time constraints
+ test_all_sizes(
+ false) // Only test obj_size(rand()) due to time constraints
{
select_random_shard_to_inject_write_error(k, m);
// We will inject specifically as part of our sequence in this sequence
setup_inject = false;
- if (!test_all_sizes)
- {
+ if (!test_all_sizes) {
select_random_object_size();
}
}
-Sequence ceph::io_exerciser::Seq10::get_id() const
-{
+Sequence ceph::io_exerciser::Seq10::get_id() const {
return Sequence::SEQUENCE_SEQ10;
}
-std::string ceph::io_exerciser::Seq10::get_name() const
-{
+std::string ceph::io_exerciser::Seq10::get_name() const {
return "Sequential writes of length " + std::to_string(length) +
- " with queue depth 1"
- " first injecting a failed write and read it to ensure it rolls back, then"
- " successfully writing the data and reading the write the ensure it is applied";
+ " with queue depth 1"
+ " first injecting a failed write and read it to ensure it rolls back, "
+ "then"
+ " successfully writing the data and reading the write the ensure it "
+ "is applied";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq10::_next()
-{
- if (!inject_error_done)
- {
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq10::_next() {
+ if (!inject_error_done) {
inject_error_done = true;
return InjectWriteErrorOp::generate(*shard_to_inject, 0, 0,
std::numeric_limits<uint64_t>::max());
- }
- else if (!failed_write_done)
- {
+ } else if (!failed_write_done) {
failed_write_done = true;
read_done = false;
barrier = true;
return SingleFailedWriteOp::generate(offset, length);
- }
- else if (failed_write_done && !read_done)
- {
+ } else if (failed_write_done && !read_done) {
read_done = true;
barrier = true;
return SingleReadOp::generate(offset, length);
- }
- else if (!clear_inject_done)
- {
+ } else if (!clear_inject_done) {
clear_inject_done = true;
return ClearWriteErrorInjectOp::generate(*shard_to_inject, 0);
- }
- else if (!successful_write_done)
- {
+ } else if (!successful_write_done) {
successful_write_done = true;
read_done = false;
barrier = true;
return SingleWriteOp::generate(offset, length);
- }
- else if (successful_write_done && !read_done)
- {
+ } else if (successful_write_done && !read_done) {
read_done = true;
return SingleReadOp::generate(offset, length);
- }
- else if (successful_write_done && read_done)
- {
+ } else if (successful_write_done && read_done) {
offset++;
inject_error_done = false;
failed_write_done = false;
successful_write_done = false;
if (offset + length >= obj_size) {
- if (!test_all_lengths)
- {
+ if (!test_all_lengths) {
done = true;
return BarrierOp::generate();
}
offset = 0;
length++;
if (length > obj_size) {
- if (!test_all_sizes)
- {
+ if (!test_all_sizes) {
done = true;
return BarrierOp::generate();
}
}
return BarrierOp::generate();
- }
- else
- {
+ } else {
ceph_abort_msg("Sequence in undefined state. Aborting");
return DoneOp::generate();
}
#include "IoSequence.h"
-namespace ceph
-{
- namespace io_exerciser
- {
- class EcIoSequence : public IoSequence
- {
- public:
- virtual bool is_supported(Sequence sequence) const override;
- static std::unique_ptr<IoSequence>
- generate_sequence(Sequence s,
- std::pair<int,int> obj_size_range,
- int k,
- int m,
- int seed );
+namespace ceph {
+namespace io_exerciser {
+class EcIoSequence : public IoSequence {
+ public:
+ virtual bool is_supported(Sequence sequence) const override;
+ static std::unique_ptr<IoSequence> generate_sequence(
+ Sequence s, std::pair<int, int> obj_size_range, int k, int m, int seed);
- protected:
- bool setup_inject;
- bool clear_inject;
- std::optional<uint64_t> shard_to_inject;
- InjectOpType inject_op_type;
+ protected:
+ bool setup_inject;
+ bool clear_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);
- // Writes cannot be sent to injected on shard zero, so selections seperated out
- void select_random_data_shard_to_inject_read_error(int k, int m);
- void select_random_data_shard_to_inject_write_error(int k, int m);
- void select_random_shard_to_inject_read_error(int k, int m);
- void select_random_shard_to_inject_write_error(int k, int m);
- void generate_random_read_inject_type();
- void generate_random_write_inject_type();
- };
+ // Writes cannot be sent to injected on shard zero, so selections seperated
+ // out
+ void select_random_data_shard_to_inject_read_error(int k, int m);
+ void select_random_data_shard_to_inject_write_error(int k, int m);
+ void select_random_shard_to_inject_read_error(int k, int m);
+ void select_random_shard_to_inject_write_error(int k, int m);
+ void generate_random_read_inject_type();
+ void generate_random_write_inject_type();
+};
- class ReadInjectSequence : public EcIoSequence
- {
- public:
- ReadInjectSequence(std::pair<int,int> obj_size_range, int seed, Sequence s, int k, int m);
+class ReadInjectSequence : public EcIoSequence {
+ public:
+ ReadInjectSequence(std::pair<int, int> obj_size_range, int seed, Sequence s,
+ int k, int m);
- Sequence get_id() const override;
- std::string get_name() const override;
- virtual std::unique_ptr<IoOp> next() override;
- std::unique_ptr<IoOp> _next() override;
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ virtual std::unique_ptr<IoOp> next() override;
+ std::unique_ptr<IoOp> _next() override;
- private:
- std::unique_ptr<IoSequence> child_sequence;
- std::unique_ptr<IoOp> nextOp;
- };
+ private:
+ std::unique_ptr<IoSequence> child_sequence;
+ std::unique_ptr<IoOp> nextOp;
+};
- class Seq10: public EcIoSequence {
- public:
- Seq10(std::pair<int,int> obj_size_range, int seed, int k, int m);
+class Seq10 : public EcIoSequence {
+ public:
+ Seq10(std::pair<int, int> obj_size_range, int seed, int k, int m);
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
- private:
- uint64_t offset;
- uint64_t length;
+ private:
+ uint64_t offset;
+ uint64_t length;
- bool inject_error_done;
- bool failed_write_done;
- bool read_done;
- bool clear_inject_done;
- bool successful_write_done;
- bool test_all_lengths;
- bool test_all_sizes;
- };
- }
-}
\ No newline at end of file
+ bool inject_error_done;
+ bool failed_write_done;
+ bool read_done;
+ bool clear_inject_done;
+ bool successful_write_done;
+ bool test_all_lengths;
+ bool test_all_sizes;
+};
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
#include "IoOp.h"
#include "fmt/format.h"
-
#include "include/ceph_assert.h"
using IoOp = ceph::io_exerciser::IoOp;
using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp;
using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
-namespace
-{
- std::string value_to_string(uint64_t v)
- {
- if (v < 1024 || (v % 1024) != 0)
- {
- return std::to_string(v);
- }
- else if (v < 1024*1024 || (v % (1024 * 1024)) != 0 )
- {
- return std::to_string(v / 1024) + "K";
- }
- else
- {
- return std::to_string(v / 1024 / 1024) + "M";
- }
+namespace {
+std::string value_to_string(uint64_t v) {
+ if (v < 1024 || (v % 1024) != 0) {
+ return std::to_string(v);
+ } else if (v < 1024 * 1024 || (v % (1024 * 1024)) != 0) {
+ return std::to_string(v / 1024) + "K";
+ } else {
+ return std::to_string(v / 1024 / 1024) + "M";
}
}
+} // namespace
-IoOp::IoOp()
-{
-
-}
-
-template<OpType opType>
-ceph::io_exerciser::TestOp<opType>::TestOp() : IoOp()
-{
+IoOp::IoOp() {}
-}
-
-DoneOp::DoneOp() : TestOp<OpType::Done>()
-{
+template <OpType opType>
+ceph::io_exerciser::TestOp<opType>::TestOp() : IoOp() {}
-}
+DoneOp::DoneOp() : TestOp<OpType::Done>() {}
-std::string DoneOp::to_string(uint64_t block_size) const
-{
- return "Done";
-}
+std::string DoneOp::to_string(uint64_t block_size) const { return "Done"; }
-std::unique_ptr<DoneOp> DoneOp::generate()
-{
+std::unique_ptr<DoneOp> DoneOp::generate() {
return std::make_unique<DoneOp>();
}
-BarrierOp::BarrierOp() : TestOp<OpType::Barrier>()
-{
+BarrierOp::BarrierOp() : TestOp<OpType::Barrier>() {}
-}
-
-std::unique_ptr<BarrierOp> BarrierOp::generate()
-{
+std::unique_ptr<BarrierOp> BarrierOp::generate() {
return std::make_unique<BarrierOp>();
}
-std::string BarrierOp::to_string(uint64_t block_size) const
-{
+std::string BarrierOp::to_string(uint64_t block_size) const {
return "Barrier";
}
-CreateOp::CreateOp(uint64_t size) : TestOp<OpType::Create>(),
- size(size)
-{
-
-}
+CreateOp::CreateOp(uint64_t size) : TestOp<OpType::Create>(), size(size) {}
-std::unique_ptr<CreateOp> CreateOp::generate(uint64_t size)
-{
+std::unique_ptr<CreateOp> CreateOp::generate(uint64_t size) {
return std::make_unique<CreateOp>(size);
}
-std::string CreateOp::to_string(uint64_t block_size) const
-{
+std::string CreateOp::to_string(uint64_t block_size) const {
return "Create (size=" + value_to_string(size * block_size) + ")";
}
-RemoveOp::RemoveOp() : TestOp<OpType::Remove>()
-{
-
-}
+RemoveOp::RemoveOp() : TestOp<OpType::Remove>() {}
-std::unique_ptr<RemoveOp> RemoveOp::generate()
-{
+std::unique_ptr<RemoveOp> RemoveOp::generate() {
return std::make_unique<RemoveOp>();
}
-std::string RemoveOp::to_string(uint64_t block_size) const
-{
- return "Remove";
-}
+std::string RemoveOp::to_string(uint64_t block_size) const { return "Remove"; }
-template<OpType opType, int numIOs>
-ceph::io_exerciser::ReadWriteOp<opType, numIOs>
- ::ReadWriteOp(std::array<uint64_t, numIOs>&& offset,
- std::array<uint64_t, numIOs>&& length) :
- TestOp<opType>(),
- offset(offset),
- length(length)
-{
- auto compare = [](uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2)
- {
- if (offset1 < offset2)
- {
- ceph_assert( offset1 + length1 <= offset2 );
- }
- else
- {
- ceph_assert( offset2 + length2 <= offset1 );
+template <OpType opType, int numIOs>
+ceph::io_exerciser::ReadWriteOp<opType, numIOs>::ReadWriteOp(
+ std::array<uint64_t, numIOs>&& offset,
+ std::array<uint64_t, numIOs>&& length)
+ : TestOp<opType>(), offset(offset), length(length) {
+ auto compare = [](uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2) {
+ if (offset1 < offset2) {
+ ceph_assert(offset1 + length1 <= offset2);
+ } else {
+ ceph_assert(offset2 + length2 <= offset1);
}
};
- if (numIOs > 1)
- {
- for (int i = 0; i < numIOs-1; i++)
- {
- for (int j = i + 1; j < numIOs; j++)
- {
+ if (numIOs > 1) {
+ for (int i = 0; i < numIOs - 1; i++) {
+ for (int j = i + 1; j < numIOs; j++) {
compare(offset[i], length[i], offset[j], length[j]);
}
}
}
}
-template<OpType opType, int numIOs>
-std::string ceph::io_exerciser::ReadWriteOp<opType, numIOs>
- ::to_string(uint64_t block_size) const
-{
+template <OpType opType, int numIOs>
+std::string ceph::io_exerciser::ReadWriteOp<opType, numIOs>::to_string(
+ uint64_t block_size) const {
std::string offset_length_desc;
- if (numIOs > 0)
- {
- offset_length_desc += fmt::format("offset1={}",
- value_to_string(this->offset[0] * block_size));
- offset_length_desc += fmt::format(",length1={}",
- value_to_string(this->length[0] * block_size));
- for (int i = 1; i < numIOs; i++)
- {
- offset_length_desc += fmt::format(",offset{}={}",
- i+1,
- value_to_string(this->offset[i] * block_size));
- offset_length_desc += fmt::format(",length{}={}",
- i+1,
- value_to_string(this->length[i] * block_size));
+ if (numIOs > 0) {
+ offset_length_desc += fmt::format(
+ "offset1={}", value_to_string(this->offset[0] * block_size));
+ offset_length_desc += fmt::format(
+ ",length1={}", value_to_string(this->length[0] * block_size));
+ for (int i = 1; i < numIOs; i++) {
+ offset_length_desc += fmt::format(
+ ",offset{}={}", i + 1, value_to_string(this->offset[i] * block_size));
+ offset_length_desc += fmt::format(
+ ",length{}={}", i + 1, value_to_string(this->length[i] * block_size));
}
}
- switch(opType)
- {
+ switch (opType) {
case OpType::Read:
- [[ fallthrough ]];
+ [[fallthrough]];
case OpType::Read2:
- [[ fallthrough ]];
+ [[fallthrough]];
case OpType::Read3:
return fmt::format("Read{} ({})", numIOs, offset_length_desc);
case OpType::Write:
- [[ fallthrough ]];
+ [[fallthrough]];
case OpType::Write2:
- [[ fallthrough ]];
+ [[fallthrough]];
case OpType::Write3:
return fmt::format("Write{} ({})", numIOs, offset_length_desc);
case OpType::FailedWrite:
- [[ fallthrough ]];
+ [[fallthrough]];
case OpType::FailedWrite2:
- [[ fallthrough ]];
+ [[fallthrough]];
case OpType::FailedWrite3:
return fmt::format("FailedWrite{} ({})", numIOs, offset_length_desc);
default:
- ceph_abort_msg(fmt::format("Unsupported op type by ReadWriteOp ({})", opType));
+ ceph_abort_msg(
+ fmt::format("Unsupported op type by ReadWriteOp ({})", opType));
}
}
-SingleReadOp::SingleReadOp(uint64_t offset, uint64_t length) :
- ReadWriteOp<OpType::Read, 1>({offset}, {length})
-{
-
-}
+SingleReadOp::SingleReadOp(uint64_t offset, uint64_t length)
+ : ReadWriteOp<OpType::Read, 1>({offset}, {length}) {}
std::unique_ptr<SingleReadOp> SingleReadOp::generate(uint64_t offset,
- uint64_t length)
-{
+ uint64_t length) {
return std::make_unique<SingleReadOp>(offset, length);
}
-DoubleReadOp::DoubleReadOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2) :
- ReadWriteOp<OpType::Read2, 2>({offset1, offset2}, {length1, length2})
-{
+DoubleReadOp::DoubleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2)
+ : ReadWriteOp<OpType::Read2, 2>({offset1, offset2}, {length1, length2}) {}
-}
-
-std::unique_ptr<DoubleReadOp> DoubleReadOp::generate(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2)
-{
+std::unique_ptr<DoubleReadOp> DoubleReadOp::generate(uint64_t offset1,
+ uint64_t length1,
+ uint64_t offset2,
+ uint64_t length2) {
return std::make_unique<DoubleReadOp>(offset1, length1, offset2, length2);
}
-TripleReadOp::TripleReadOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3) :
- ReadWriteOp<OpType::Read3, 3>({offset1, offset2, offset3},
- {length1, length2, length3})
-{
-
-}
+TripleReadOp::TripleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2, uint64_t offset3, uint64_t length3)
+ : ReadWriteOp<OpType::Read3, 3>({offset1, offset2, offset3},
+ {length1, length2, length3}) {}
-std::unique_ptr<TripleReadOp> TripleReadOp::generate(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3)
-{
- return std::make_unique<TripleReadOp>(offset1, length1,
- offset2, length2,
+std::unique_ptr<TripleReadOp> TripleReadOp::generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2,
+ uint64_t offset3, uint64_t length3) {
+ return std::make_unique<TripleReadOp>(offset1, length1, offset2, length2,
offset3, length3);
}
-SingleWriteOp::SingleWriteOp(uint64_t offset, uint64_t length) :
- ReadWriteOp<OpType::Write, 1>({offset}, {length})
-{
+SingleWriteOp::SingleWriteOp(uint64_t offset, uint64_t length)
+ : ReadWriteOp<OpType::Write, 1>({offset}, {length}) {}
-}
-
-std::unique_ptr<SingleWriteOp> SingleWriteOp::generate(uint64_t offset, uint64_t length)
-{
+std::unique_ptr<SingleWriteOp> SingleWriteOp::generate(uint64_t offset,
+ uint64_t length) {
return std::make_unique<SingleWriteOp>(offset, length);
}
DoubleWriteOp::DoubleWriteOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2) :
- ReadWriteOp<OpType::Write2, 2>({offset1, offset2}, {length1, length2})
-{
+ uint64_t offset2, uint64_t length2)
+ : ReadWriteOp<OpType::Write2, 2>({offset1, offset2}, {length1, length2}) {}
-}
-
-std::unique_ptr<DoubleWriteOp> DoubleWriteOp::generate(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2)
-{
+std::unique_ptr<DoubleWriteOp> DoubleWriteOp::generate(uint64_t offset1,
+ uint64_t length1,
+ uint64_t offset2,
+ uint64_t length2) {
return std::make_unique<DoubleWriteOp>(offset1, length1, offset2, length2);
}
TripleWriteOp::TripleWriteOp(uint64_t offset1, uint64_t length1,
uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3) :
- ReadWriteOp<OpType::Write3, 3>({offset1, offset2, offset3}, {length1, length2, length3})
-{
-
-}
-
-std::unique_ptr<TripleWriteOp> TripleWriteOp::generate(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3)
-{
- return std::make_unique<TripleWriteOp>(offset1, length1,
- offset2, length2,
+ uint64_t offset3, uint64_t length3)
+ : ReadWriteOp<OpType::Write3, 3>({offset1, offset2, offset3},
+ {length1, length2, length3}) {}
+
+std::unique_ptr<TripleWriteOp> TripleWriteOp::generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2,
+ uint64_t offset3, uint64_t length3) {
+ return std::make_unique<TripleWriteOp>(offset1, length1, offset2, length2,
offset3, length3);
}
-SingleFailedWriteOp::SingleFailedWriteOp(uint64_t offset, uint64_t length) :
- ReadWriteOp<OpType::FailedWrite, 1>({offset}, {length})
-{
+SingleFailedWriteOp::SingleFailedWriteOp(uint64_t offset, uint64_t length)
+ : ReadWriteOp<OpType::FailedWrite, 1>({offset}, {length}) {}
-}
-
-std::unique_ptr<SingleFailedWriteOp> SingleFailedWriteOp::generate(uint64_t offset,
- uint64_t length)
-{
+std::unique_ptr<SingleFailedWriteOp> SingleFailedWriteOp::generate(
+ uint64_t offset, uint64_t length) {
return std::make_unique<SingleFailedWriteOp>(offset, length);
}
DoubleFailedWriteOp::DoubleFailedWriteOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2) :
- ReadWriteOp<OpType::FailedWrite2, 2>({offset1, offset2}, {length1, length2})
-{
-
-}
+ uint64_t offset2, uint64_t length2)
+ : ReadWriteOp<OpType::FailedWrite2, 2>({offset1, offset2},
+ {length1, length2}) {}
-std::unique_ptr<DoubleFailedWriteOp> DoubleFailedWriteOp::generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2)
-{
- return std::make_unique<DoubleFailedWriteOp>(offset1, length1, offset2, length2);
+std::unique_ptr<DoubleFailedWriteOp> DoubleFailedWriteOp::generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2) {
+ return std::make_unique<DoubleFailedWriteOp>(offset1, length1, offset2,
+ length2);
}
TripleFailedWriteOp::TripleFailedWriteOp(uint64_t offset1, uint64_t length1,
uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3) :
- ReadWriteOp<OpType::FailedWrite3, 3>({offset1, offset2, offset3},
- {length1, length2, length3})
-{
-
-}
+ uint64_t offset3, uint64_t length3)
+ : ReadWriteOp<OpType::FailedWrite3, 3>({offset1, offset2, offset3},
+ {length1, length2, length3}) {}
-std::unique_ptr<TripleFailedWriteOp> TripleFailedWriteOp::generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2,
- uint64_t offset3,
- uint64_t length3)
-{
- return std::make_unique<TripleFailedWriteOp>(offset1, length1,
- offset2, length2,
- offset3, length3);
+std::unique_ptr<TripleFailedWriteOp> TripleFailedWriteOp::generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2,
+ uint64_t offset3, uint64_t length3) {
+ return std::make_unique<TripleFailedWriteOp>(offset1, length1, offset2,
+ length2, offset3, length3);
}
template <ceph::io_exerciser::OpType opType>
-ceph::io_exerciser::InjectErrorOp<opType>
- ::InjectErrorOp(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration) :
- TestOp<opType>(),
- shard(shard),
- type(type),
- when(when),
- duration(duration)
-{
-
-}
+ceph::io_exerciser::InjectErrorOp<opType>::InjectErrorOp(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration)
+ : TestOp<opType>(),
+ shard(shard),
+ type(type),
+ when(when),
+ duration(duration) {}
template <ceph::io_exerciser::OpType opType>
-std::string ceph::io_exerciser::InjectErrorOp<opType>::to_string(uint64_t blocksize) const
-{
+std::string ceph::io_exerciser::InjectErrorOp<opType>::to_string(
+ uint64_t blocksize) const {
std::string_view inject_type = get_inject_type_string();
- return fmt::format("Inject {} error on shard {} of type {}"
- " after {} successful inject(s) lasting {} inject(s)",
- inject_type, shard, type.value_or(0),
- when.value_or(0), duration.value_or(1));
-}
-
-ceph::io_exerciser::InjectReadErrorOp::InjectReadErrorOp(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration) :
- InjectErrorOp<OpType::InjectReadError>(shard, type, when, duration)
-{
-
-}
-
-std::unique_ptr<ceph::io_exerciser::InjectReadErrorOp> ceph::io_exerciser
- ::InjectReadErrorOp::generate(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration)
-{
+ return fmt::format(
+ "Inject {} error on shard {} of type {}"
+ " after {} successful inject(s) lasting {} inject(s)",
+ inject_type, shard, type.value_or(0), when.value_or(0),
+ duration.value_or(1));
+}
+
+ceph::io_exerciser::InjectReadErrorOp::InjectReadErrorOp(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration)
+ : InjectErrorOp<OpType::InjectReadError>(shard, type, when, duration) {}
+
+std::unique_ptr<ceph::io_exerciser::InjectReadErrorOp>
+ceph::io_exerciser ::InjectReadErrorOp::generate(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration) {
return std::make_unique<InjectReadErrorOp>(shard, type, when, duration);
}
-ceph::io_exerciser::InjectWriteErrorOp::InjectWriteErrorOp(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration) :
- InjectErrorOp<OpType::InjectWriteError>(shard, type, when, duration)
-{
+ceph::io_exerciser::InjectWriteErrorOp::InjectWriteErrorOp(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration)
+ : InjectErrorOp<OpType::InjectWriteError>(shard, type, when, duration) {}
-}
-
-std::unique_ptr<ceph::io_exerciser::InjectWriteErrorOp> ceph::io_exerciser
- ::InjectWriteErrorOp::generate(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration)
-{
+std::unique_ptr<ceph::io_exerciser::InjectWriteErrorOp>
+ceph::io_exerciser ::InjectWriteErrorOp::generate(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration) {
return std::make_unique<InjectWriteErrorOp>(shard, type, when, duration);
}
-
-
template <ceph::io_exerciser::OpType opType>
-ceph::io_exerciser::ClearErrorInjectOp<opType>
- ::ClearErrorInjectOp(int shard, const std::optional<uint64_t>& type) :
- TestOp<opType>(),
- shard(shard),
- type(type)
-{
-
-}
+ceph::io_exerciser::ClearErrorInjectOp<opType>::ClearErrorInjectOp(
+ int shard, const std::optional<uint64_t>& type)
+ : TestOp<opType>(), shard(shard), type(type) {}
template <ceph::io_exerciser::OpType opType>
-std::string ceph::io_exerciser::ClearErrorInjectOp<opType>::to_string(uint64_t blocksize) const
-{
+std::string ceph::io_exerciser::ClearErrorInjectOp<opType>::to_string(
+ uint64_t blocksize) const {
std::string_view inject_type = get_inject_type_string();
- return fmt::format("Clear {} injects on shard {} of type {}",
- inject_type, shard, type.value_or(0));
+ return fmt::format("Clear {} injects on shard {} of type {}", inject_type,
+ shard, type.value_or(0));
}
-ceph::io_exerciser::ClearReadErrorInjectOp::ClearReadErrorInjectOp(int shard,
- const std::optional<uint64_t>& type) :
- ClearErrorInjectOp<OpType::ClearReadErrorInject>(shard, type)
-{
-
-}
+ceph::io_exerciser::ClearReadErrorInjectOp::ClearReadErrorInjectOp(
+ int shard, const std::optional<uint64_t>& type)
+ : ClearErrorInjectOp<OpType::ClearReadErrorInject>(shard, type) {}
-std::unique_ptr<ceph::io_exerciser::ClearReadErrorInjectOp> ceph::io_exerciser
- ::ClearReadErrorInjectOp::generate(int shard, const std::optional<uint64_t>& type)
-{
+std::unique_ptr<ceph::io_exerciser::ClearReadErrorInjectOp>
+ceph::io_exerciser ::ClearReadErrorInjectOp::generate(
+ int shard, const std::optional<uint64_t>& type) {
return std::make_unique<ClearReadErrorInjectOp>(shard, type);
}
-ceph::io_exerciser::ClearWriteErrorInjectOp::ClearWriteErrorInjectOp(int shard,
- const std::optional<uint64_t>& type) :
- ClearErrorInjectOp<OpType::ClearWriteErrorInject>(shard, type)
-{
-
-}
+ceph::io_exerciser::ClearWriteErrorInjectOp::ClearWriteErrorInjectOp(
+ int shard, const std::optional<uint64_t>& type)
+ : ClearErrorInjectOp<OpType::ClearWriteErrorInject>(shard, type) {}
-std::unique_ptr<ceph::io_exerciser::ClearWriteErrorInjectOp> ceph::io_exerciser
- ::ClearWriteErrorInjectOp::generate(int shard, const std::optional<uint64_t>& type)
-{
+std::unique_ptr<ceph::io_exerciser::ClearWriteErrorInjectOp>
+ceph::io_exerciser ::ClearWriteErrorInjectOp::generate(
+ int shard, const std::optional<uint64_t>& type) {
return std::make_unique<ClearWriteErrorInjectOp>(shard, type);
}
\ No newline at end of file
#pragma once
#include <array>
+#include <memory>
#include <optional>
#include <string>
-#include <memory>
#include "OpType.h"
*/
namespace ceph {
- namespace io_exerciser {
-
- class IoOp
- {
- public:
- IoOp();
- virtual ~IoOp() = default;
- virtual std::string to_string(uint64_t block_size) const = 0;
- virtual constexpr OpType getOpType() const = 0;
- };
-
- template<OpType opType>
- class TestOp : public IoOp
- {
- public:
- TestOp();
- constexpr OpType getOpType() const override { return opType; }
- };
-
- class DoneOp : public TestOp<OpType::Done>
- {
- public:
- DoneOp();
- static std::unique_ptr<DoneOp> generate();
- std::string to_string(uint64_t block_size) const override;
- };
-
- class BarrierOp : public TestOp<OpType::Barrier>
- {
- public:
- BarrierOp();
- static std::unique_ptr<BarrierOp> generate();
- std::string to_string(uint64_t block_size) const override;
- };
-
- class CreateOp : public TestOp<OpType::Create>
- {
- public:
- CreateOp(uint64_t size);
- static std::unique_ptr<CreateOp> generate(uint64_t size);
- std::string to_string(uint64_t block_size) const override;
- uint64_t size;
- };
-
- class RemoveOp : public TestOp<OpType::Remove>
- {
- public:
- RemoveOp();
- static std::unique_ptr<RemoveOp> generate();
- std::string to_string(uint64_t block_size) const override;
- };
-
- template<OpType opType, int numIOs>
- class ReadWriteOp : public TestOp<opType>
- {
- public:
- std::array<uint64_t, numIOs> offset;
- std::array<uint64_t, numIOs> length;
-
- protected:
- ReadWriteOp(std::array<uint64_t, numIOs>&& offset,
- std::array<uint64_t, numIOs>&& length);
- std::string to_string(uint64_t block_size) const override;
- };
-
- class SingleReadOp : public ReadWriteOp<OpType::Read, 1>
- {
- public:
- SingleReadOp(uint64_t offset, uint64_t length);
- static std::unique_ptr<SingleReadOp> generate(uint64_t offset,
- uint64_t length);
- };
-
- class DoubleReadOp : public ReadWriteOp<OpType::Read2, 2>
- {
- public:
- DoubleReadOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2);
- static std::unique_ptr<DoubleReadOp> generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2);
- };
-
- class TripleReadOp : public ReadWriteOp<OpType::Read3, 3>
- {
- public:
- TripleReadOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3);
- static std::unique_ptr<TripleReadOp> generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2,
- uint64_t offset3,
- uint64_t length3);
- };
-
- class SingleWriteOp : public ReadWriteOp<OpType::Write, 1>
- {
- public:
- SingleWriteOp(uint64_t offset, uint64_t length);
- static std::unique_ptr<SingleWriteOp> generate(uint64_t offset,
+namespace io_exerciser {
+
+class IoOp {
+ public:
+ IoOp();
+ virtual ~IoOp() = default;
+ virtual std::string to_string(uint64_t block_size) const = 0;
+ virtual constexpr OpType getOpType() const = 0;
+};
+
+template <OpType opType>
+class TestOp : public IoOp {
+ public:
+ TestOp();
+ constexpr OpType getOpType() const override { return opType; }
+};
+
+class DoneOp : public TestOp<OpType::Done> {
+ public:
+ DoneOp();
+ static std::unique_ptr<DoneOp> generate();
+ std::string to_string(uint64_t block_size) const override;
+};
+
+class BarrierOp : public TestOp<OpType::Barrier> {
+ public:
+ BarrierOp();
+ static std::unique_ptr<BarrierOp> generate();
+ std::string to_string(uint64_t block_size) const override;
+};
+
+class CreateOp : public TestOp<OpType::Create> {
+ public:
+ CreateOp(uint64_t size);
+ static std::unique_ptr<CreateOp> generate(uint64_t size);
+ std::string to_string(uint64_t block_size) const override;
+ uint64_t size;
+};
+
+class RemoveOp : public TestOp<OpType::Remove> {
+ public:
+ RemoveOp();
+ static std::unique_ptr<RemoveOp> generate();
+ std::string to_string(uint64_t block_size) const override;
+};
+
+template <OpType opType, int numIOs>
+class ReadWriteOp : public TestOp<opType> {
+ public:
+ std::array<uint64_t, numIOs> offset;
+ std::array<uint64_t, numIOs> length;
+
+ protected:
+ ReadWriteOp(std::array<uint64_t, numIOs>&& offset,
+ std::array<uint64_t, numIOs>&& length);
+ std::string to_string(uint64_t block_size) const override;
+};
+
+class SingleReadOp : public ReadWriteOp<OpType::Read, 1> {
+ public:
+ SingleReadOp(uint64_t offset, uint64_t length);
+ static std::unique_ptr<SingleReadOp> generate(uint64_t offset,
+ uint64_t length);
+};
+
+class DoubleReadOp : public ReadWriteOp<OpType::Read2, 2> {
+ public:
+ DoubleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2);
+ static std::unique_ptr<DoubleReadOp> generate(uint64_t offset1,
+ uint64_t length1,
+ uint64_t offset2,
+ uint64_t length2);
+};
+
+class TripleReadOp : public ReadWriteOp<OpType::Read3, 3> {
+ public:
+ TripleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2, uint64_t offset3, uint64_t length3);
+ static std::unique_ptr<TripleReadOp> generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2,
+ uint64_t offset3, uint64_t length3);
+};
+
+class SingleWriteOp : public ReadWriteOp<OpType::Write, 1> {
+ public:
+ SingleWriteOp(uint64_t offset, uint64_t length);
+ static std::unique_ptr<SingleWriteOp> generate(uint64_t offset,
+ uint64_t length);
+};
+
+class DoubleWriteOp : public ReadWriteOp<OpType::Write2, 2> {
+ public:
+ DoubleWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2);
+ static std::unique_ptr<DoubleWriteOp> generate(uint64_t offset1,
+ uint64_t length1,
+ uint64_t offset2,
+ uint64_t length2);
+};
+
+class TripleWriteOp : public ReadWriteOp<OpType::Write3, 3> {
+ public:
+ TripleWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2, uint64_t offset3, uint64_t length3);
+ static std::unique_ptr<TripleWriteOp> generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2,
+ uint64_t offset3, uint64_t length3);
+};
+
+class SingleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite, 1> {
+ public:
+ SingleFailedWriteOp(uint64_t offset, uint64_t length);
+ static std::unique_ptr<SingleFailedWriteOp> generate(uint64_t offset,
uint64_t length);
- };
-
- class DoubleWriteOp : public ReadWriteOp<OpType::Write2, 2>
- {
- public:
- DoubleWriteOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2);
- static std::unique_ptr<DoubleWriteOp> generate(uint64_t offset1,
+};
+
+class DoubleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite2, 2> {
+ public:
+ DoubleFailedWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2);
+ static std::unique_ptr<DoubleFailedWriteOp> generate(uint64_t offset1,
uint64_t length1,
uint64_t offset2,
uint64_t length2);
- };
-
- class TripleWriteOp : public ReadWriteOp<OpType::Write3, 3>
- {
- public:
- TripleWriteOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3);
- static std::unique_ptr<TripleWriteOp> generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2,
- uint64_t offset3,
- uint64_t length3);
- };
-
- class SingleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite, 1>
- {
- public:
- SingleFailedWriteOp(uint64_t offset, uint64_t length);
- static std::unique_ptr<SingleFailedWriteOp> generate(uint64_t offset,
- uint64_t length);
- };
-
- class DoubleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite2, 2>
- {
- public:
- DoubleFailedWriteOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2);
- static std::unique_ptr<DoubleFailedWriteOp> generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2);
- };
-
- class TripleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite3, 3>
- {
- public:
- TripleFailedWriteOp(uint64_t offset1, uint64_t length1,
- uint64_t offset2, uint64_t length2,
- uint64_t offset3, uint64_t length3);
- static std::unique_ptr<TripleFailedWriteOp> generate(uint64_t offset1,
- uint64_t length1,
- uint64_t offset2,
- uint64_t length2,
- uint64_t offset3,
- uint64_t length3);
- };
-
- template <ceph::io_exerciser::OpType opType>
- class InjectErrorOp : public TestOp<opType>
- {
- public:
- InjectErrorOp(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration);
-
- std::string to_string(uint64_t block_size) const override;
-
- int shard;
- std::optional<uint64_t> type;
- std::optional<uint64_t> when;
- std::optional<uint64_t> duration;
-
- protected:
- virtual inline constexpr std::string_view get_inject_type_string() const = 0;
- };
-
- class InjectReadErrorOp : public InjectErrorOp<OpType::InjectReadError>
- {
- public:
- InjectReadErrorOp(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration);
-
- static std::unique_ptr<InjectReadErrorOp> generate(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration);
-
- protected:
- inline constexpr std::string_view get_inject_type_string() const override
- { return "read"; }
- };
-
- class InjectWriteErrorOp : public InjectErrorOp<OpType::InjectWriteError>
- {
- public:
- InjectWriteErrorOp(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration);
-
- static std::unique_ptr<InjectWriteErrorOp> generate(int shard,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration);
-
- protected:
- inline constexpr std::string_view get_inject_type_string() const override
- { return "write"; }
- };
-
- template <ceph::io_exerciser::OpType opType>
- class ClearErrorInjectOp : public TestOp<opType>
- {
- public:
- ClearErrorInjectOp(int shard, const std::optional<uint64_t>& type);
-
- std::string to_string(uint64_t block_size) const override;
-
- int shard;
- std::optional<uint64_t> type;
-
- protected:
- virtual inline constexpr std::string_view get_inject_type_string() const = 0;
- };
-
- class ClearReadErrorInjectOp : public ClearErrorInjectOp<OpType::ClearReadErrorInject>
- {
- public:
- ClearReadErrorInjectOp(int shard, const std::optional<uint64_t>& type);
-
- static std::unique_ptr<ClearReadErrorInjectOp> generate(int shard,
- const std::optional<uint64_t>& type);
-
- protected:
- inline constexpr std::string_view get_inject_type_string() const override
- { return "read"; }
- };
-
- class ClearWriteErrorInjectOp : public ClearErrorInjectOp<OpType::ClearWriteErrorInject>
- {
- public:
- ClearWriteErrorInjectOp(int shard, const std::optional<uint64_t>& type);
-
- static std::unique_ptr<ClearWriteErrorInjectOp> generate(int shard,
- const std::optional<uint64_t>& type);
-
- protected:
- inline constexpr std::string_view get_inject_type_string() const override
- { return "write"; }
- };
+};
+
+class TripleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite3, 3> {
+ public:
+ TripleFailedWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2,
+ uint64_t length2, uint64_t offset3, uint64_t length3);
+ static std::unique_ptr<TripleFailedWriteOp> generate(
+ uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2,
+ uint64_t offset3, uint64_t length3);
+};
+
+template <ceph::io_exerciser::OpType opType>
+class InjectErrorOp : public TestOp<opType> {
+ public:
+ InjectErrorOp(int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration);
+
+ std::string to_string(uint64_t block_size) const override;
+
+ int shard;
+ std::optional<uint64_t> type;
+ std::optional<uint64_t> when;
+ std::optional<uint64_t> duration;
+
+ protected:
+ virtual inline constexpr std::string_view get_inject_type_string() const = 0;
+};
+
+class InjectReadErrorOp : public InjectErrorOp<OpType::InjectReadError> {
+ public:
+ InjectReadErrorOp(int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration);
+
+ static std::unique_ptr<InjectReadErrorOp> generate(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration);
+
+ protected:
+ inline constexpr std::string_view get_inject_type_string() const override {
+ return "read";
+ }
+};
+
+class InjectWriteErrorOp : public InjectErrorOp<OpType::InjectWriteError> {
+ public:
+ InjectWriteErrorOp(int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration);
+
+ static std::unique_ptr<InjectWriteErrorOp> generate(
+ int shard, const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration);
+
+ protected:
+ inline constexpr std::string_view get_inject_type_string() const override {
+ return "write";
+ }
+};
+
+template <ceph::io_exerciser::OpType opType>
+class ClearErrorInjectOp : public TestOp<opType> {
+ public:
+ ClearErrorInjectOp(int shard, const std::optional<uint64_t>& type);
+
+ std::string to_string(uint64_t block_size) const override;
+
+ int shard;
+ std::optional<uint64_t> type;
+
+ protected:
+ virtual inline constexpr std::string_view get_inject_type_string() const = 0;
+};
+
+class ClearReadErrorInjectOp
+ : public ClearErrorInjectOp<OpType::ClearReadErrorInject> {
+ public:
+ ClearReadErrorInjectOp(int shard, const std::optional<uint64_t>& type);
+
+ static std::unique_ptr<ClearReadErrorInjectOp> generate(
+ int shard, const std::optional<uint64_t>& type);
+
+ protected:
+ inline constexpr std::string_view get_inject_type_string() const override {
+ return "read";
+ }
+};
+
+class ClearWriteErrorInjectOp
+ : public ClearErrorInjectOp<OpType::ClearWriteErrorInject> {
+ public:
+ ClearWriteErrorInjectOp(int shard, const std::optional<uint64_t>& type);
+
+ static std::unique_ptr<ClearWriteErrorInjectOp> generate(
+ int shard, const std::optional<uint64_t>& type);
+
+ protected:
+ inline constexpr std::string_view get_inject_type_string() const override {
+ return "write";
}
-}
\ No newline at end of file
+};
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
using Sequence = ceph::io_exerciser::Sequence;
using IoSequence = ceph::io_exerciser::IoSequence;
-std::ostream& ceph::io_exerciser::operator<<(std::ostream& os, const Sequence& seq)
-{
- switch (seq)
- {
+std::ostream& ceph::io_exerciser::operator<<(std::ostream& os,
+ const Sequence& seq) {
+ switch (seq) {
case Sequence::SEQUENCE_SEQ0:
os << "SEQUENCE_SEQ0";
break;
return os;
}
-bool IoSequence::is_supported(Sequence sequence) const
-{
+bool IoSequence::is_supported(Sequence sequence) const {
return sequence != Sequence::SEQUENCE_SEQ10;
}
-std::unique_ptr<IoSequence> IoSequence::generate_sequence(Sequence s,
- std::pair<int,int> obj_size_range,
- int seed)
-{
+std::unique_ptr<IoSequence> IoSequence::generate_sequence(
+ Sequence s, std::pair<int, int> obj_size_range, int seed) {
switch (s) {
case Sequence::SEQUENCE_SEQ0:
return std::make_unique<Seq0>(obj_size_range, seed);
case Sequence::SEQUENCE_SEQ9:
return std::make_unique<Seq9>(obj_size_range, seed);
case Sequence::SEQUENCE_SEQ10:
- ceph_abort_msg("Sequence 10 only supported for erasure coded pools "
- "through the EcIoSequence interface");
+ ceph_abort_msg(
+ "Sequence 10 only supported for erasure coded pools "
+ "through the EcIoSequence interface");
return nullptr;
default:
break;
return nullptr;
}
-IoSequence::IoSequence(std::pair<int,int> obj_size_range,
- int seed) :
- min_obj_size(obj_size_range.first), max_obj_size(obj_size_range.second),
- create(true), barrier(false), done(false), remove(false),
- obj_size(min_obj_size), step(-1), seed(seed)
-{
+IoSequence::IoSequence(std::pair<int, int> obj_size_range, int seed)
+ : min_obj_size(obj_size_range.first),
+ max_obj_size(obj_size_range.second),
+ create(true),
+ barrier(false),
+ done(false),
+ remove(false),
+ obj_size(min_obj_size),
+ step(-1),
+ seed(seed) {
rng.seed(seed);
}
-std::string ceph::io_exerciser::IoSequence::get_name_with_seqseed() const
-{
+std::string ceph::io_exerciser::IoSequence::get_name_with_seqseed() const {
return get_name() + " (seqseed " + std::to_string(get_seed()) + ")";
}
-int IoSequence::get_step() const
-{
- return step;
-}
+int IoSequence::get_step() const { return step; }
-int IoSequence::get_seed() const
-{
- return seed;
-}
+int IoSequence::get_seed() const { return seed; }
-void IoSequence::set_min_object_size(uint64_t size)
-{
+void IoSequence::set_min_object_size(uint64_t size) {
min_obj_size = size;
if (obj_size < size) {
obj_size = size;
}
}
-void IoSequence::set_max_object_size(uint64_t size)
-{
+void IoSequence::set_max_object_size(uint64_t size) {
max_obj_size = size;
if (obj_size > size) {
done = true;
}
}
-void IoSequence::select_random_object_size()
-{
+void IoSequence::select_random_object_size() {
if (max_obj_size != min_obj_size) {
obj_size = min_obj_size + rng(max_obj_size - min_obj_size);
}
}
-std::unique_ptr<IoOp> IoSequence::increment_object_size()
-{
+std::unique_ptr<IoOp> IoSequence::increment_object_size() {
obj_size++;
if (obj_size > max_obj_size) {
done = true;
return BarrierOp::generate();
}
-Sequence IoSequence::getNextSupportedSequenceId() const
-{
+Sequence IoSequence::getNextSupportedSequenceId() const {
Sequence sequence = get_id();
++sequence;
- for (;sequence < Sequence::SEQUENCE_END;
- ++sequence)
- {
- if (is_supported(sequence))
- {
+ for (; sequence < Sequence::SEQUENCE_END; ++sequence) {
+ if (is_supported(sequence)) {
return sequence;
}
}
return Sequence::SEQUENCE_END;
}
-std::unique_ptr<IoOp> IoSequence::next()
-{
+std::unique_ptr<IoOp> IoSequence::next() {
step++;
if (remove) {
remove = false;
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)
+ : IoSequence(obj_size_range, seed), offset(0) {
select_random_object_size();
length = 1 + rng(obj_size - 1);
}
-Sequence ceph::io_exerciser::Seq0::get_id() const
-{
+Sequence ceph::io_exerciser::Seq0::get_id() const {
return Sequence::SEQUENCE_SEQ0;
}
-std::string ceph::io_exerciser::Seq0::get_name() const
-{
+std::string ceph::io_exerciser::Seq0::get_name() const {
return "Sequential reads of length " + std::to_string(length) +
- " with queue depth 1";
+ " with queue depth 1";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq0::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq0::_next() {
std::unique_ptr<IoOp> r;
if (offset >= obj_size) {
done = true;
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)
+ : IoSequence(obj_size_range, seed) {
select_random_object_size();
count = 3 * obj_size;
}
-Sequence ceph::io_exerciser::Seq1::get_id() const
-{
+Sequence ceph::io_exerciser::Seq1::get_id() const {
return Sequence::SEQUENCE_SEQ1;
}
-std::string ceph::io_exerciser::Seq1::get_name() const
-{
+std::string ceph::io_exerciser::Seq1::get_name() const {
return "Random offset, random length read/write I/O with queue depth 1";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq1::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq1::_next() {
barrier = true;
if (count-- == 0) {
done = true;
uint64_t offset = rng(obj_size - 1);
uint64_t length = 1 + rng(obj_size - 1 - offset);
- if (rng(2) != 0)
- {
+ if (rng(2) != 0) {
return SingleWriteOp::generate(offset, length);
- }
- else
- {
+ } else {
return SingleReadOp::generate(offset, length);
}
}
+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) :
- IoSequence(obj_size_range, seed), offset(0), length(0)
-{
-
-}
-
-Sequence ceph::io_exerciser::Seq2::get_id() const
-{
+Sequence ceph::io_exerciser::Seq2::get_id() const {
return Sequence::SEQUENCE_SEQ2;
}
-std::string ceph::io_exerciser::Seq2::get_name() const
-{
+std::string ceph::io_exerciser::Seq2::get_name() const {
return "Permutations of offset and length read I/O";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq2::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq2::_next() {
length++;
if (length > obj_size - offset) {
length = 1;
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)
+ : IoSequence(obj_size_range, seed), offset1(0), offset2(0) {
set_min_object_size(2);
}
-Sequence ceph::io_exerciser::Seq3::get_id() const
-{
+Sequence ceph::io_exerciser::Seq3::get_id() const {
return Sequence::SEQUENCE_SEQ3;
}
-std::string ceph::io_exerciser::Seq3::get_name() const
-{
+std::string ceph::io_exerciser::Seq3::get_name() const {
return "Permutations of offset 2-region 1-block read I/O";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq3::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq3::_next() {
offset2++;
if (offset2 >= obj_size - offset1) {
offset2 = 1;
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)
+ : IoSequence(obj_size_range, seed), offset1(0), offset2(1) {
set_min_object_size(3);
}
-Sequence ceph::io_exerciser::Seq4::get_id() const
-{
+Sequence ceph::io_exerciser::Seq4::get_id() const {
return Sequence::SEQUENCE_SEQ4;
}
-std::string ceph::io_exerciser::Seq4::get_name() const
-{
+std::string ceph::io_exerciser::Seq4::get_name() const {
return "Permutations of offset 3-region 1-block read I/O";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq4::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq4::_next() {
offset2++;
if (offset2 >= obj_size - offset1) {
offset2 = 2;
return increment_object_size();
}
}
- return TripleReadOp::generate(offset1, 1, (offset1 + offset2), 1, (offset1 * 2 + offset2) / 2, 1);
+ return TripleReadOp::generate(offset1, 1, (offset1 + offset2), 1,
+ (offset1 * 2 + offset2) / 2, 1);
}
+ceph::io_exerciser::Seq5::Seq5(std::pair<int, int> obj_size_range, int seed)
+ : IoSequence(obj_size_range, seed),
+ offset(0),
+ length(1),
+ doneread(false),
+ donebarrier(false) {}
-
-ceph::io_exerciser::Seq5::Seq5(std::pair<int,int> obj_size_range, int seed) :
- IoSequence(obj_size_range, seed), offset(0), length(1),
- doneread(false), donebarrier(false)
-{
-
-}
-
-Sequence ceph::io_exerciser::Seq5::get_id() const
-{
+Sequence ceph::io_exerciser::Seq5::get_id() const {
return Sequence::SEQUENCE_SEQ5;
}
-std::string ceph::io_exerciser::Seq5::get_name() const
-{
+std::string ceph::io_exerciser::Seq5::get_name() const {
return "Permutation of length sequential writes";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq5::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq5::_next() {
if (offset >= obj_size) {
if (!doneread) {
if (!donebarrier) {
return r;
}
+ceph::io_exerciser::Seq6::Seq6(std::pair<int, int> obj_size_range, int seed)
+ : IoSequence(obj_size_range, seed),
+ offset(0),
+ length(1),
+ doneread(false),
+ donebarrier(false) {}
-
-ceph::io_exerciser::Seq6::Seq6(std::pair<int,int> obj_size_range, int seed) :
- IoSequence(obj_size_range, seed), offset(0), length(1),
- doneread(false), donebarrier(false)
-{
-
-}
-
-Sequence ceph::io_exerciser::Seq6::get_id() const
-{
+Sequence ceph::io_exerciser::Seq6::get_id() const {
return Sequence::SEQUENCE_SEQ6;
}
-std::string ceph::io_exerciser::Seq6::get_name() const
-{
+std::string ceph::io_exerciser::Seq6::get_name() const {
return "Permutation of length sequential writes, different alignment";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq6::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq6::_next() {
if (offset >= obj_size) {
if (!doneread) {
if (!donebarrier) {
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)
+ : IoSequence(obj_size_range, seed) {
set_min_object_size(2);
offset = obj_size;
}
-Sequence ceph::io_exerciser::Seq7::get_id() const
-{
+Sequence ceph::io_exerciser::Seq7::get_id() const {
return Sequence::SEQUENCE_SEQ7;
}
-std::string ceph::io_exerciser::Seq7::get_name() const
-{
+std::string ceph::io_exerciser::Seq7::get_name() const {
return "Permutations of offset 2-region 1-block writes";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq7::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq7::_next() {
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
if (offset == 0) {
doneread = false;
donebarrier = false;
- offset = obj_size+1;
+ offset = obj_size + 1;
return increment_object_size();
}
offset--;
- if (offset == obj_size/2) {
+ if (offset == obj_size / 2) {
return _next();
}
doneread = false;
donebarrier = false;
- return DoubleReadOp::generate(offset, 1, obj_size/2, 1);
+ return DoubleReadOp::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)
+ : IoSequence(obj_size_range, seed), offset1(0), offset2(1) {
set_min_object_size(3);
}
-Sequence ceph::io_exerciser::Seq8::get_id() const
-{
+Sequence ceph::io_exerciser::Seq8::get_id() const {
return Sequence::SEQUENCE_SEQ8;
}
-std::string ceph::io_exerciser::Seq8::get_name() const
-{
+std::string ceph::io_exerciser::Seq8::get_name() const {
return "Permutations of offset 3-region 1-block write I/O";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq8::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq8::_next() {
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
}
doneread = false;
donebarrier = false;
- return TripleWriteOp::generate(offset1, 1, offset1 + offset2, 1, (offset1 * 2 + offset2)/2, 1);
+ return TripleWriteOp::generate(offset1, 1, offset1 + offset2, 1,
+ (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) :
- IoSequence(obj_size_range, seed), offset(0), length(0)
-{
-
-}
-
-Sequence ceph::io_exerciser::Seq9::get_id() const
-{
+Sequence ceph::io_exerciser::Seq9::get_id() const {
return Sequence::SEQUENCE_SEQ9;
}
-std::string ceph::io_exerciser::Seq9::get_name() const
-{
+std::string ceph::io_exerciser::Seq9::get_name() const {
return "Permutations of offset and length write I/O";
}
-std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq9::_next()
-{
+std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq9::_next() {
if (!doneread) {
if (!donebarrier) {
donebarrier = true;
#pragma once
#include "IoOp.h"
-
#include "include/random.h"
/* Overview
*/
namespace ceph {
- namespace io_exerciser {
-
- enum class Sequence {
- SEQUENCE_SEQ0,
- SEQUENCE_SEQ1,
- SEQUENCE_SEQ2,
- SEQUENCE_SEQ3,
- SEQUENCE_SEQ4,
- SEQUENCE_SEQ5,
- SEQUENCE_SEQ6,
- SEQUENCE_SEQ7,
- SEQUENCE_SEQ8,
- SEQUENCE_SEQ9,
- SEQUENCE_SEQ10,
-
- SEQUENCE_END,
- SEQUENCE_BEGIN = SEQUENCE_SEQ0
- };
-
- inline Sequence operator++( Sequence& s )
- {
- return s = (Sequence)(((int)(s) + 1));
- }
-
- std::ostream& operator<<(std::ostream& os, const Sequence& seq);
-
- /* I/O Sequences */
-
- class IoSequence {
- public:
- virtual ~IoSequence() = default;
-
- virtual Sequence get_id() const = 0;
- virtual std::string get_name_with_seqseed() const;
- virtual std::string get_name() const = 0;
- int get_step() const;
- int get_seed() const;
-
- virtual Sequence getNextSupportedSequenceId() const;
- virtual std::unique_ptr<IoOp> next();
-
- 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 );
-
- protected:
- uint64_t min_obj_size;
- uint64_t max_obj_size;
- bool create;
- bool barrier;
- bool done;
- bool remove;
- 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);
-
- virtual std::unique_ptr<IoOp> _next() = 0;
-
- void set_min_object_size(uint64_t size);
- void set_max_object_size(uint64_t size);
- void select_random_object_size();
- std::unique_ptr<IoOp> increment_object_size();
- };
-
- class Seq0: public IoSequence {
- public:
- Seq0(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- uint64_t offset;
- uint64_t length;
- };
-
- class Seq1: public IoSequence {
- public:
- Seq1(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- int count;
- };
-
- class Seq2: public IoSequence {
- public:
- Seq2(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- uint64_t offset;
- uint64_t length;
- };
-
- class Seq3: public IoSequence {
- public:
- Seq3(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
- private:
- uint64_t offset1;
- uint64_t offset2;
- };
-
- class Seq4: public IoSequence {
- public:
- Seq4(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- uint64_t offset1;
- uint64_t offset2;
- };
-
- class Seq5: public IoSequence {
- public:
- Seq5(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- uint64_t offset;
- uint64_t length;
- bool doneread;
- bool donebarrier;
- };
-
- class Seq6: public IoSequence {
- public:
- Seq6(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- uint64_t offset;
- uint64_t length;
- bool doneread;
- bool donebarrier;
- };
-
- class Seq7: public IoSequence {
- public:
- Seq7(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
-
- private:
- uint64_t offset;
- bool doneread = true;
- bool donebarrier = false;
- };
-
- class Seq8: public IoSequence {
- public:
- Seq8(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
- private:
- uint64_t offset1;
- uint64_t offset2;
- bool doneread = true;
- bool donebarrier = false;
- };
-
- class Seq9: public IoSequence {
- private:
- uint64_t offset;
- uint64_t length;
- bool doneread = true;
- bool donebarrier = false;
-
- public:
- Seq9(std::pair<int,int> obj_size_range, int seed);
-
- Sequence get_id() const override;
- std::string get_name() const override;
- std::unique_ptr<IoOp> _next() override;
- };
- }
-}
\ No newline at end of file
+namespace io_exerciser {
+
+enum class Sequence {
+ SEQUENCE_SEQ0,
+ SEQUENCE_SEQ1,
+ SEQUENCE_SEQ2,
+ SEQUENCE_SEQ3,
+ SEQUENCE_SEQ4,
+ SEQUENCE_SEQ5,
+ SEQUENCE_SEQ6,
+ SEQUENCE_SEQ7,
+ SEQUENCE_SEQ8,
+ SEQUENCE_SEQ9,
+ SEQUENCE_SEQ10,
+
+ SEQUENCE_END,
+ SEQUENCE_BEGIN = SEQUENCE_SEQ0
+};
+
+inline Sequence operator++(Sequence& s) {
+ return s = (Sequence)(((int)(s) + 1));
+}
+
+std::ostream& operator<<(std::ostream& os, const Sequence& seq);
+
+/* I/O Sequences */
+
+class IoSequence {
+ public:
+ virtual ~IoSequence() = default;
+
+ virtual Sequence get_id() const = 0;
+ virtual std::string get_name_with_seqseed() const;
+ virtual std::string get_name() const = 0;
+ int get_step() const;
+ int get_seed() const;
+
+ virtual Sequence getNextSupportedSequenceId() const;
+ virtual std::unique_ptr<IoOp> next();
+
+ 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);
+
+ protected:
+ uint64_t min_obj_size;
+ uint64_t max_obj_size;
+ bool create;
+ bool barrier;
+ bool done;
+ bool remove;
+ 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);
+
+ virtual std::unique_ptr<IoOp> _next() = 0;
+
+ void set_min_object_size(uint64_t size);
+ void set_max_object_size(uint64_t size);
+ void select_random_object_size();
+ std::unique_ptr<IoOp> increment_object_size();
+};
+
+class Seq0 : public IoSequence {
+ public:
+ Seq0(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset;
+ uint64_t length;
+};
+
+class Seq1 : public IoSequence {
+ public:
+ Seq1(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ int count;
+};
+
+class Seq2 : public IoSequence {
+ public:
+ Seq2(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset;
+ uint64_t length;
+};
+
+class Seq3 : public IoSequence {
+ public:
+ Seq3(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset1;
+ uint64_t offset2;
+};
+
+class Seq4 : public IoSequence {
+ public:
+ Seq4(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset1;
+ uint64_t offset2;
+};
+
+class Seq5 : public IoSequence {
+ public:
+ Seq5(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset;
+ uint64_t length;
+ bool doneread;
+ bool donebarrier;
+};
+
+class Seq6 : public IoSequence {
+ public:
+ Seq6(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset;
+ uint64_t length;
+ bool doneread;
+ bool donebarrier;
+};
+
+class Seq7 : public IoSequence {
+ public:
+ Seq7(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset;
+ bool doneread = true;
+ bool donebarrier = false;
+};
+
+class Seq8 : public IoSequence {
+ public:
+ Seq8(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+
+ private:
+ uint64_t offset1;
+ uint64_t offset2;
+ bool doneread = true;
+ bool donebarrier = false;
+};
+
+class Seq9 : public IoSequence {
+ private:
+ uint64_t offset;
+ uint64_t length;
+ bool doneread = true;
+ bool donebarrier = false;
+
+ public:
+ Seq9(std::pair<int, int> obj_size_range, int seed);
+
+ Sequence get_id() const override;
+ std::string get_name() const override;
+ std::unique_ptr<IoOp> _next() override;
+};
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
#include "JsonStructures.h"
-#include "common/ceph_json.h"
#include "OpType.h"
+#include "common/ceph_json.h"
using namespace ceph::io_exerciser::json;
-JSONStructure::JSONStructure(std::shared_ptr<ceph::Formatter> formatter) :
- formatter(formatter)
-{
-
-}
+JSONStructure::JSONStructure(std::shared_ptr<ceph::Formatter> formatter)
+ : formatter(formatter) {}
-std::string JSONStructure::encode_json()
-{
+std::string JSONStructure::encode_json() {
oss.clear();
dump();
OSDMapRequest::OSDMapRequest(const std::string& pool_name,
const std::string& object,
const std::string& nspace,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- pool(pool_name),
- object(object),
- nspace(nspace)
-{
-
-}
-
-OSDMapRequest::OSDMapRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter),
+ pool(pool_name),
+ object(object),
+ nspace(nspace) {}
-}
+OSDMapRequest::OSDMapRequest(std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void OSDMapRequest::decode_json(JSONObj* obj)
-{
+void OSDMapRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("pool", pool, obj);
JSONDecoder::decode_json("object", object, obj);
JSONDecoder::decode_json("format", format, obj);
}
-void OSDMapRequest::dump() const
-{
+void OSDMapRequest::dump() const {
formatter->open_object_section("OSDMapRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("pool", pool, formatter.get());
formatter->close_section();
}
-OSDMapReply::OSDMapReply(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-
-}
+OSDMapReply::OSDMapReply(std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void OSDMapReply::decode_json(JSONObj* obj)
-{
+void OSDMapReply::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("epoch", epoch, obj);
JSONDecoder::decode_json("pool", pool, obj);
JSONDecoder::decode_json("pool_id", pool_id, obj);
JSONDecoder::decode_json("acting_primary", acting_primary, obj);
}
-void OSDMapReply::dump() const
-{
+void OSDMapReply::dump() const {
formatter->open_object_section("OSDMapReply");
::encode_json("epoch", epoch, formatter.get());
::encode_json("pool", pool, formatter.get());
formatter->close_section();
}
-ceph::io_exerciser::json::OSDPoolGetRequest
- ::OSDPoolGetRequest(const std::string& pool_name,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- pool(pool_name)
-{
+ceph::io_exerciser::json::OSDPoolGetRequest ::OSDPoolGetRequest(
+ const std::string& pool_name, std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter), pool(pool_name) {}
-}
-
-ceph::io_exerciser::json::OSDPoolGetRequest
- ::OSDPoolGetRequest(JSONObj* obj,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+ceph::io_exerciser::json::OSDPoolGetRequest ::OSDPoolGetRequest(
+ JSONObj* obj, std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {
ceph::io_exerciser::json::OSDPoolGetRequest::decode_json(obj);
}
JSONDecoder::decode_json("format", format, obj);
}
-void ceph::io_exerciser::json::OSDPoolGetRequest::dump() const
-{
+void ceph::io_exerciser::json::OSDPoolGetRequest::dump() const {
formatter->open_object_section("OSDPoolGetRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("pool", pool, formatter.get());
formatter->close_section();
}
-ceph::io_exerciser::json::OSDPoolGetReply
- ::OSDPoolGetReply(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-
-}
+ceph::io_exerciser::json::OSDPoolGetReply ::OSDPoolGetReply(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
void ceph::io_exerciser::json::OSDPoolGetReply::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("erasure_code_profile", erasure_code_profile, obj);
}
-void ceph::io_exerciser::json::OSDPoolGetReply::dump() const
-{
+void ceph::io_exerciser::json::OSDPoolGetReply::dump() const {
formatter->open_object_section("OSDPoolGetReply");
::encode_json("erasure_code_profile", erasure_code_profile, formatter.get());
formatter->close_section();
}
-ceph::io_exerciser::json::OSDECProfileGetRequest
- ::OSDECProfileGetRequest(const std::string& profile_name,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- name(profile_name)
-{
+ceph::io_exerciser::json::OSDECProfileGetRequest ::OSDECProfileGetRequest(
+ const std::string& profile_name, std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter), name(profile_name) {}
-}
-
-ceph::io_exerciser::json::OSDECProfileGetRequest
- ::OSDECProfileGetRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-
-}
+ceph::io_exerciser::json::OSDECProfileGetRequest ::OSDECProfileGetRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void ceph::io_exerciser::json::OSDECProfileGetRequest::decode_json(JSONObj* obj) {
+void ceph::io_exerciser::json::OSDECProfileGetRequest::decode_json(
+ JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("name", name, obj);
JSONDecoder::decode_json("format", format, obj);
}
-void ceph::io_exerciser::json::OSDECProfileGetRequest::dump() const
-{
+void ceph::io_exerciser::json::OSDECProfileGetRequest::dump() const {
formatter->open_object_section("OSDECProfileGetRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("name", name, formatter.get());
formatter->close_section();
}
-ceph::io_exerciser::json::OSDECProfileGetReply
- ::OSDECProfileGetReply(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-
-}
+ceph::io_exerciser::json::OSDECProfileGetReply ::OSDECProfileGetReply(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
void ceph::io_exerciser::json::OSDECProfileGetReply::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("crush-device-class", crush_device_class, obj);
JSONDecoder::decode_json("crush-failure-domain", crush_failure_domain, obj);
JSONDecoder::decode_json("crush-num-failure-domains",
- crush_num_failure_domains,
- obj);
+ crush_num_failure_domains, obj);
JSONDecoder::decode_json("crush-osds-per-failure-domain",
- crush_osds_per_failure_domain,
- obj);
+ crush_osds_per_failure_domain, obj);
JSONDecoder::decode_json("crush-root", crush_root, obj);
JSONDecoder::decode_json("jerasure-per-chunk-alignment",
- jerasure_per_chunk_alignment,
- obj);
+ jerasure_per_chunk_alignment, obj);
JSONDecoder::decode_json("k", k, obj);
JSONDecoder::decode_json("m", m, obj);
JSONDecoder::decode_json("plugin", plugin, obj);
JSONDecoder::decode_json("w", w, obj);
}
-void ceph::io_exerciser::json::OSDECProfileGetReply::dump() const
-{
+void ceph::io_exerciser::json::OSDECProfileGetReply::dump() const {
formatter->open_object_section("OSDECProfileGetReply");
- ::encode_json("crush-device-class",
- crush_device_class,
- formatter.get());
- ::encode_json("crush-failure-domain",
- crush_failure_domain,
- formatter.get());
- ::encode_json("crush-num-failure-domains",
- crush_num_failure_domains,
+ ::encode_json("crush-device-class", crush_device_class, formatter.get());
+ ::encode_json("crush-failure-domain", crush_failure_domain, formatter.get());
+ ::encode_json("crush-num-failure-domains", crush_num_failure_domains,
formatter.get());
- ::encode_json("crush-osds-per-failure-domain",
- crush_osds_per_failure_domain,
+ ::encode_json("crush-osds-per-failure-domain", crush_osds_per_failure_domain,
formatter.get());
::encode_json("crush-root", crush_root, formatter.get());
- ::encode_json("jerasure-per-chunk-alignment",
- jerasure_per_chunk_alignment,
+ ::encode_json("jerasure-per-chunk-alignment", jerasure_per_chunk_alignment,
formatter.get());
::encode_json("k", k, formatter.get());
::encode_json("m", m, formatter.get());
formatter->close_section();
}
-ceph::io_exerciser::json::OSDECProfileSetRequest
- ::OSDECProfileSetRequest(const std::string& name,
- const std::vector<std::string>& profile,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- name(name),
- profile(profile)
-{
+ceph::io_exerciser::json::OSDECProfileSetRequest ::OSDECProfileSetRequest(
+ const std::string& name, const std::vector<std::string>& profile,
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter), name(name), profile(profile) {}
-}
-
-OSDECProfileSetRequest
- ::OSDECProfileSetRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+OSDECProfileSetRequest ::OSDECProfileSetRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-}
-
-void OSDECProfileSetRequest::decode_json(JSONObj* obj)
-{
+void OSDECProfileSetRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("name", name, obj);
JSONDecoder::decode_json("profile", profile, obj);
}
-void OSDECProfileSetRequest::dump() const
-{
+void OSDECProfileSetRequest::dump() const {
formatter->open_object_section("OSDECProfileSetRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("name", name, formatter.get());
formatter->close_section();
}
-OSDECPoolCreateRequest::OSDECPoolCreateRequest(const std::string& pool,
- const std::string& erasure_code_profile,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- pool(pool),
- erasure_code_profile(erasure_code_profile)
-{
-
-}
+OSDECPoolCreateRequest::OSDECPoolCreateRequest(
+ const std::string& pool, const std::string& erasure_code_profile,
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter),
+ pool(pool),
+ erasure_code_profile(erasure_code_profile) {}
-OSDECPoolCreateRequest
- ::OSDECPoolCreateRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-}
+OSDECPoolCreateRequest ::OSDECPoolCreateRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void OSDECPoolCreateRequest::decode_json(JSONObj* obj)
-{
+void OSDECPoolCreateRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("pool", pool, obj);
JSONDecoder::decode_json("pool_type", pool_type, obj);
JSONDecoder::decode_json("erasure_code_profile", erasure_code_profile, obj);
}
-void OSDECPoolCreateRequest::dump() const
-{
+void OSDECPoolCreateRequest::dump() const {
formatter->open_object_section("OSDECPoolCreateRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("pool", pool, formatter.get());
OSDSetRequest::OSDSetRequest(const std::string& key,
const std::optional<bool>& yes_i_really_mean_it,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- key(key),
- yes_i_really_mean_it(yes_i_really_mean_it)
-{
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter),
+ key(key),
+ yes_i_really_mean_it(yes_i_really_mean_it) {}
-}
-
-OSDSetRequest::OSDSetRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-}
+OSDSetRequest::OSDSetRequest(std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void OSDSetRequest::decode_json(JSONObj* obj)
-{
+void OSDSetRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("key", key, obj);
JSONDecoder::decode_json("yes_i_really_mean_it", yes_i_really_mean_it, obj);
}
-void OSDSetRequest::dump() const
-{
+void OSDSetRequest::dump() const {
formatter->open_object_section("OSDSetRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("key", key, formatter.get());
formatter->close_section();
}
-BalancerOffRequest::BalancerOffRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+BalancerOffRequest::BalancerOffRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-}
-
-void ceph::io_exerciser::json::BalancerOffRequest::decode_json(JSONObj* obj)
-{
+void ceph::io_exerciser::json::BalancerOffRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
}
-void BalancerOffRequest::dump() const
-{
+void BalancerOffRequest::dump() const {
formatter->open_object_section("BalancerOffRequest");
::encode_json("prefix", prefix, formatter.get());
formatter->close_section();
}
-BalancerStatusRequest
- ::BalancerStatusRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-
-}
+BalancerStatusRequest ::BalancerStatusRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void ceph::io_exerciser::json::BalancerStatusRequest::decode_json(JSONObj* obj)
-{
+void ceph::io_exerciser::json::BalancerStatusRequest::decode_json(
+ JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
}
-void BalancerStatusRequest::dump() const
-{
+void BalancerStatusRequest::dump() const {
formatter->open_object_section("BalancerStatusRequest");
::encode_json("prefix", prefix, formatter.get());
formatter->close_section();
}
-BalancerStatusReply::BalancerStatusReply(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+BalancerStatusReply::BalancerStatusReply(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-}
-
-void BalancerStatusReply::decode_json(JSONObj* obj)
-{
+void BalancerStatusReply::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("active", active, obj);
JSONDecoder::decode_json("last_optimization_duration",
last_optimization_duration, obj);
JSONDecoder::decode_json("last_optimization_started",
last_optimization_started, obj);
JSONDecoder::decode_json("mode", mode, obj);
- JSONDecoder::decode_json("no_optimization_needed",
- no_optimization_needed, obj);
+ JSONDecoder::decode_json("no_optimization_needed", no_optimization_needed,
+ obj);
JSONDecoder::decode_json("optimize_result", optimize_result, obj);
-
}
-void BalancerStatusReply::dump() const
-{
+void BalancerStatusReply::dump() const {
formatter->open_object_section("BalancerStatusReply");
::encode_json("active", active, formatter.get());
- ::encode_json("last_optimization_duration",
- last_optimization_duration,
+ ::encode_json("last_optimization_duration", last_optimization_duration,
formatter.get());
- ::encode_json("last_optimization_started",
- last_optimization_started,
+ ::encode_json("last_optimization_started", last_optimization_started,
formatter.get());
::encode_json("mode", mode, formatter.get());
- ::encode_json("no_optimization_needed",
- no_optimization_needed,
- formatter.get());
- ::encode_json("optimize_result",
- optimize_result,
+ ::encode_json("no_optimization_needed", no_optimization_needed,
formatter.get());
+ ::encode_json("optimize_result", optimize_result, formatter.get());
formatter->close_section();
}
const std::string& name,
const std::string& value,
const std::optional<bool>& force,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- who(who),
- name(name),
- value(value),
- force(force)
-{
-
-}
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter),
+ who(who),
+ name(name),
+ value(value),
+ force(force) {}
-ConfigSetRequest::ConfigSetRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+ConfigSetRequest::ConfigSetRequest(std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-}
-
-void ConfigSetRequest::decode_json(JSONObj* obj)
-{
+void ConfigSetRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("who", who, obj);
JSONDecoder::decode_json("name", name, obj);
JSONDecoder::decode_json("force", force, obj);
}
-void ConfigSetRequest::dump() const
-{
+void ConfigSetRequest::dump() const {
formatter->open_object_section("ConfigSetRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("who", who, formatter.get());
formatter->close_section();
}
-InjectECErrorRequest::InjectECErrorRequest(InjectOpType injectOpType,
- const std::string& pool,
- const std::string& objname,
- int shardid,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- pool(pool),
- objname(objname),
- shardid(shardid),
- type(type),
- when(when),
- duration(duration)
-{
- switch(injectOpType)
- {
+InjectECErrorRequest::InjectECErrorRequest(
+ InjectOpType injectOpType, const std::string& pool,
+ const std::string& objname, int shardid,
+ const std::optional<uint64_t>& type, const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration,
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter),
+ pool(pool),
+ objname(objname),
+ shardid(shardid),
+ type(type),
+ when(when),
+ duration(duration) {
+ switch (injectOpType) {
case InjectOpType::ReadEIO:
- [[ fallthrough ]];
+ [[fallthrough]];
case InjectOpType::ReadMissingShard:
prefix = "injectecreaderr";
break;
case InjectOpType::WriteFailAndRollback:
- [[ fallthrough ]];
+ [[fallthrough]];
case InjectOpType::WriteOSDAbort:
prefix = "injectecwriteerr";
break;
}
}
-InjectECErrorRequest
- ::InjectECErrorRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
+InjectECErrorRequest ::InjectECErrorRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-}
-
-void InjectECErrorRequest::dump() const
-{
+void InjectECErrorRequest::dump() const {
formatter->open_object_section("InjectECErrorRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("pool", pool, formatter.get());
formatter->close_section();
}
-void InjectECErrorRequest::decode_json(JSONObj* obj)
-{
+void InjectECErrorRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("pool", pool, obj);
JSONDecoder::decode_json("objname", objname, obj);
JSONDecoder::decode_json("duration", duration, obj);
}
-
-
-InjectECClearErrorRequest::InjectECClearErrorRequest(InjectOpType injectOpType,
- const std::string& pool,
- const std::string& objname,
- int shardid,
- const std::optional<uint64_t>& type,
- std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter),
- pool(pool),
- objname(objname),
- shardid(shardid),
- type(type)
-{
- switch(injectOpType)
- {
- case InjectOpType::ReadEIO:
- [[ fallthrough ]];
+InjectECClearErrorRequest::InjectECClearErrorRequest(
+ InjectOpType injectOpType, const std::string& pool,
+ const std::string& objname, int shardid,
+ const std::optional<uint64_t>& type,
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter),
+ pool(pool),
+ objname(objname),
+ shardid(shardid),
+ type(type) {
+ switch (injectOpType) {
+ case InjectOpType::ReadEIO:
+ [[fallthrough]];
case InjectOpType::ReadMissingShard:
prefix = "injectecclearreaderr";
break;
case InjectOpType::WriteFailAndRollback:
- [[ fallthrough ]];
+ [[fallthrough]];
case InjectOpType::WriteOSDAbort:
prefix = "injectecclearwriteerr";
break;
}
}
-InjectECClearErrorRequest
- ::InjectECClearErrorRequest(std::shared_ptr<ceph::Formatter> formatter) :
- JSONStructure(formatter)
-{
-
-}
+InjectECClearErrorRequest ::InjectECClearErrorRequest(
+ std::shared_ptr<ceph::Formatter> formatter)
+ : JSONStructure(formatter) {}
-void InjectECClearErrorRequest::dump() const
-{
+void InjectECClearErrorRequest::dump() const {
formatter->open_object_section("InjectECErrorRequest");
::encode_json("prefix", prefix, formatter.get());
::encode_json("pool", pool, formatter.get());
formatter->close_section();
}
-void InjectECClearErrorRequest::decode_json(JSONObj* obj)
-{
+void InjectECClearErrorRequest::decode_json(JSONObj* obj) {
JSONDecoder::decode_json("prefix", prefix, obj);
JSONDecoder::decode_json("pool", pool, obj);
JSONDecoder::decode_json("objname", objname, obj);
#include <string>
#include <vector>
-#include "include/types.h"
-
#include "OpType.h"
+#include "include/types.h"
/* Overview
*
class JSONObj;
-namespace ceph
-{
- namespace io_exerciser
- {
- namespace json
- {
- class JSONStructure
- {
- public:
- JSONStructure(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- virtual ~JSONStructure() = default;
-
- std::string encode_json();
- virtual void decode_json(JSONObj* obj)=0;
- virtual void dump() const = 0;
-
- protected:
- std::shared_ptr<Formatter> formatter;
-
- private:
- std::ostringstream oss;
- };
-
- class OSDMapRequest : public JSONStructure
- {
- public:
- OSDMapRequest(const std::string& pool_name,
- const std::string& object,
- const std::string& nspace,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
- OSDMapRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "osd map";
- std::string pool;
- std::string object;
- std::string nspace;
- std::string format = "json";
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class OSDMapReply : public JSONStructure
- {
- public:
- OSDMapReply(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- epoch_t epoch;
- std::string pool;
- uint64_t pool_id;
- std::string objname;
- std::string raw_pgid;
- std::string pgid;
- std::vector<int> up;
- int up_primary;
- std::vector<int> acting;
- int acting_primary;
-
- void decode_json(JSONObj *obj);
- void dump() const;
- };
-
- class OSDPoolGetRequest : public JSONStructure
- {
- public:
- OSDPoolGetRequest(const std::string& pool_name, std::shared_ptr<ceph::Formatter> formatter = std::make_shared<JSONFormatter>(false));
- OSDPoolGetRequest(JSONObj* obj, std::shared_ptr<ceph::Formatter> formatter = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "osd pool get";
- std::string pool;
- std::string var = "erasure_code_profile";
- std::string format = "json";
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class OSDPoolGetReply : public JSONStructure
- {
- public:
- OSDPoolGetReply(std::shared_ptr<ceph::Formatter> formatter = std::make_shared<JSONFormatter>(false));
-
- std::string erasure_code_profile;
-
- void decode_json(JSONObj *obj);
- void dump() const;
- };
-
- class OSDECProfileGetRequest : public JSONStructure
- {
- public:
- OSDECProfileGetRequest(const std::string& profile_name, std::shared_ptr<ceph::Formatter> formatter = std::make_shared<JSONFormatter>(false));
- OSDECProfileGetRequest(std::shared_ptr<ceph::Formatter> formatter = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "osd pool get";
- std::string name;
- std::string format = "json";
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class OSDECProfileGetReply : public JSONStructure
- {
- public:
- OSDECProfileGetReply(std::shared_ptr<ceph::Formatter> formatter = std::make_shared<JSONFormatter>(false));
-
- std::string crush_device_class;
- std::string crush_failure_domain;
- int crush_num_failure_domains;
- int crush_osds_per_failure_domain;
- std::string crush_root;
- bool jerasure_per_chunk_alignment;
- int k;
- int m;
- std::string plugin;
- std::string technique;
- std::string w;
-
- void decode_json(JSONObj *obj);
- void dump() const;
- };
-
- class OSDECProfileSetRequest : public JSONStructure
- {
- public:
- OSDECProfileSetRequest(const std::string& name,
- const std::vector<std::string>& profile,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
- OSDECProfileSetRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "osd erasure-code-profile set";
- std::string name;
- std::vector<std::string> profile;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class OSDECPoolCreateRequest : public JSONStructure
- {
- public:
- OSDECPoolCreateRequest(const std::string& pool,
- const std::string& erasure_code_profile,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
- OSDECPoolCreateRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "osd pool create";
- std::string pool;
- std::string pool_type = "erasure";
- int pg_num = 8;
- int pgp_num = 8;
- std::string erasure_code_profile;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class OSDSetRequest : public JSONStructure
- {
- public:
- OSDSetRequest(const std::string& key,
- const std::optional<bool>& yes_i_really_mean_it
- = std::nullopt,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
- OSDSetRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "osd set";
- std::string key;
- std::optional<bool> yes_i_really_mean_it = std::nullopt;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class BalancerOffRequest : public JSONStructure
- {
- public:
- BalancerOffRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "balancer off";
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class BalancerStatusRequest : public JSONStructure
- {
- public:
- BalancerStatusRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "balancer status";
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class BalancerStatusReply : public JSONStructure
- {
- public:
- BalancerStatusReply(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- bool active;
- std::string last_optimization_duration;
- std::string last_optimization_started;
- std::string mode;
- bool no_optimization_needed;
- std::string optimize_result;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class ConfigSetRequest : public JSONStructure
- {
- public:
- ConfigSetRequest(const std::string& who,
- const std::string& name,
- const std::string& value,
- const std::optional<bool>& force = std::nullopt,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
- ConfigSetRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix = "config set";
- std::string who;
- std::string name;
- std::string value;
- std::optional<bool> force;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class InjectECErrorRequest : public JSONStructure
- {
- public:
- InjectECErrorRequest(InjectOpType injectOpType,
- const std::string& pool,
- const std::string& objname,
- int shardid,
- const std::optional<uint64_t>& type,
- const std::optional<uint64_t>& when,
- const std::optional<uint64_t>& duration,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
- InjectECErrorRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix;
- std::string pool;
- std::string objname;
- int shardid;
- std::optional<uint64_t> type;
- std::optional<uint64_t> when;
- std::optional<uint64_t> duration;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
-
- class InjectECClearErrorRequest : public JSONStructure
- {
- public:
- InjectECClearErrorRequest(InjectOpType injectOpType,
- const std::string& pool,
- const std::string& objname,
- int shardid,
- const std::optional<uint64_t>& type,
- std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- InjectECClearErrorRequest(std::shared_ptr<Formatter> formatter
- = std::make_shared<JSONFormatter>(false));
-
- std::string prefix;
- std::string pool;
- std::string objname;
- int shardid;
- std::optional<uint64_t> type;
-
- void decode_json(JSONObj* obj) override;
- void dump() const override;
- };
- }
- }
-}
\ No newline at end of file
+namespace ceph {
+namespace io_exerciser {
+namespace json {
+class JSONStructure {
+ public:
+ JSONStructure(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ virtual ~JSONStructure() = default;
+
+ std::string encode_json();
+ virtual void decode_json(JSONObj* obj) = 0;
+ virtual void dump() const = 0;
+
+ protected:
+ std::shared_ptr<Formatter> formatter;
+
+ private:
+ std::ostringstream oss;
+};
+
+class OSDMapRequest : public JSONStructure {
+ public:
+ OSDMapRequest(const std::string& pool_name, const std::string& object,
+ const std::string& nspace,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ OSDMapRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "osd map";
+ std::string pool;
+ std::string object;
+ std::string nspace;
+ std::string format = "json";
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class OSDMapReply : public JSONStructure {
+ public:
+ OSDMapReply(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ epoch_t epoch;
+ std::string pool;
+ uint64_t pool_id;
+ std::string objname;
+ std::string raw_pgid;
+ std::string pgid;
+ std::vector<int> up;
+ int up_primary;
+ std::vector<int> acting;
+ int acting_primary;
+
+ void decode_json(JSONObj* obj);
+ void dump() const;
+};
+
+class OSDPoolGetRequest : public JSONStructure {
+ public:
+ OSDPoolGetRequest(const std::string& pool_name,
+ std::shared_ptr<ceph::Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ OSDPoolGetRequest(JSONObj* obj, std::shared_ptr<ceph::Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "osd pool get";
+ std::string pool;
+ std::string var = "erasure_code_profile";
+ std::string format = "json";
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class OSDPoolGetReply : public JSONStructure {
+ public:
+ OSDPoolGetReply(std::shared_ptr<ceph::Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string erasure_code_profile;
+
+ void decode_json(JSONObj* obj);
+ void dump() const;
+};
+
+class OSDECProfileGetRequest : public JSONStructure {
+ public:
+ OSDECProfileGetRequest(const std::string& profile_name,
+ std::shared_ptr<ceph::Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ OSDECProfileGetRequest(std::shared_ptr<ceph::Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "osd pool get";
+ std::string name;
+ std::string format = "json";
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class OSDECProfileGetReply : public JSONStructure {
+ public:
+ OSDECProfileGetReply(std::shared_ptr<ceph::Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string crush_device_class;
+ std::string crush_failure_domain;
+ int crush_num_failure_domains;
+ int crush_osds_per_failure_domain;
+ std::string crush_root;
+ bool jerasure_per_chunk_alignment;
+ int k;
+ int m;
+ std::string plugin;
+ std::string technique;
+ std::string w;
+
+ void decode_json(JSONObj* obj);
+ void dump() const;
+};
+
+class OSDECProfileSetRequest : public JSONStructure {
+ public:
+ OSDECProfileSetRequest(const std::string& name,
+ const std::vector<std::string>& profile,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ OSDECProfileSetRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "osd erasure-code-profile set";
+ std::string name;
+ std::vector<std::string> profile;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class OSDECPoolCreateRequest : public JSONStructure {
+ public:
+ OSDECPoolCreateRequest(const std::string& pool,
+ const std::string& erasure_code_profile,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ OSDECPoolCreateRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "osd pool create";
+ std::string pool;
+ std::string pool_type = "erasure";
+ int pg_num = 8;
+ int pgp_num = 8;
+ std::string erasure_code_profile;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class OSDSetRequest : public JSONStructure {
+ public:
+ OSDSetRequest(const std::string& key,
+ const std::optional<bool>& yes_i_really_mean_it = std::nullopt,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ OSDSetRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "osd set";
+ std::string key;
+ std::optional<bool> yes_i_really_mean_it = std::nullopt;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class BalancerOffRequest : public JSONStructure {
+ public:
+ BalancerOffRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "balancer off";
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class BalancerStatusRequest : public JSONStructure {
+ public:
+ BalancerStatusRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "balancer status";
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class BalancerStatusReply : public JSONStructure {
+ public:
+ BalancerStatusReply(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ bool active;
+ std::string last_optimization_duration;
+ std::string last_optimization_started;
+ std::string mode;
+ bool no_optimization_needed;
+ std::string optimize_result;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class ConfigSetRequest : public JSONStructure {
+ public:
+ ConfigSetRequest(const std::string& who, const std::string& name,
+ const std::string& value,
+ const std::optional<bool>& force = std::nullopt,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ ConfigSetRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix = "config set";
+ std::string who;
+ std::string name;
+ std::string value;
+ std::optional<bool> force;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class InjectECErrorRequest : public JSONStructure {
+ public:
+ InjectECErrorRequest(InjectOpType injectOpType, const std::string& pool,
+ const std::string& objname, int shardid,
+ const std::optional<uint64_t>& type,
+ const std::optional<uint64_t>& when,
+ const std::optional<uint64_t>& duration,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+ InjectECErrorRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix;
+ std::string pool;
+ std::string objname;
+ int shardid;
+ std::optional<uint64_t> type;
+ std::optional<uint64_t> when;
+ std::optional<uint64_t> duration;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+
+class InjectECClearErrorRequest : public JSONStructure {
+ public:
+ InjectECClearErrorRequest(InjectOpType injectOpType, const std::string& pool,
+ const std::string& objname, int shardid,
+ const std::optional<uint64_t>& type,
+ std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ InjectECClearErrorRequest(std::shared_ptr<Formatter> formatter =
+ std::make_shared<JSONFormatter>(false));
+
+ std::string prefix;
+ std::string pool;
+ std::string objname;
+ int shardid;
+ std::optional<uint64_t> type;
+
+ void decode_json(JSONObj* obj) override;
+ void dump() const override;
+};
+} // namespace json
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
using Model = ceph::io_exerciser::Model;
-Model::Model(const std::string& oid, uint64_t block_size) :
-num_io(0),
-oid(oid),
-block_size(block_size)
-{
+Model::Model(const std::string& oid, uint64_t block_size)
+ : num_io(0), oid(oid), block_size(block_size) {}
-}
+const uint64_t Model::get_block_size() const { return block_size; }
-const uint64_t Model::get_block_size() const
-{
- return block_size;
-}
+const std::string Model::get_oid() const { return oid; }
-const std::string Model::get_oid() const
-{
- return oid;
-}
-
-int Model::get_num_io() const
-{
- return num_io;
-}
\ No newline at end of file
+int Model::get_num_io() const { return num_io; }
\ No newline at end of file
#pragma once
-#include "IoOp.h"
-
#include <boost/asio/io_context.hpp>
-#include "librados/librados_asio.h"
-
-#include "include/interval_set.h"
-#include "global/global_init.h"
-#include "global/global_context.h"
+#include "IoOp.h"
#include "common/Thread.h"
+#include "global/global_context.h"
+#include "global/global_init.h"
+#include "include/interval_set.h"
+#include "librados/librados_asio.h"
/* Overview
*
*/
namespace ceph {
- namespace io_exerciser {
-
- class Model
- {
- protected:
- int num_io{0};
- std::string oid;
- uint64_t block_size;
-
- public:
- Model(const std::string& oid, uint64_t block_size);
- virtual ~Model() = default;
-
- virtual bool readyForIoOp(IoOp& op) = 0;
- virtual void applyIoOp(IoOp& op) = 0;
-
- const std::string get_oid() const;
- const uint64_t get_block_size() const;
- int get_num_io() const;
- };
-
- /* Simple RADOS I/O generator */
-
-
- }
-}
\ No newline at end of file
+namespace io_exerciser {
+
+class Model {
+ protected:
+ int num_io{0};
+ std::string oid;
+ uint64_t block_size;
+
+ public:
+ Model(const std::string& oid, uint64_t block_size);
+ virtual ~Model() = default;
+
+ virtual bool readyForIoOp(IoOp& op) = 0;
+ virtual void applyIoOp(IoOp& op) = 0;
+
+ const std::string get_oid() const;
+ const uint64_t get_block_size() const;
+ int get_num_io() const;
+};
+
+/* Simple RADOS I/O generator */
+
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
using ObjectModel = ceph::io_exerciser::ObjectModel;
-ObjectModel::ObjectModel(const std::string& oid, uint64_t block_size, int seed) :
- Model(oid, block_size), created(false)
-{
+ObjectModel::ObjectModel(const std::string& oid, uint64_t block_size, int seed)
+ : Model(oid, block_size), created(false) {
rng.seed(seed);
}
-int ObjectModel::get_seed(uint64_t offset) const
-{
+int ObjectModel::get_seed(uint64_t offset) const {
ceph_assert(offset < contents.size());
return contents[offset];
}
-std::vector<int> ObjectModel::get_seed_offsets(int seed) const
-{
+std::vector<int> ObjectModel::get_seed_offsets(int seed) const {
std::vector<int> offsets;
- for (size_t i = 0; i < contents.size(); i++)
- {
- if (contents[i] == seed)
- {
+ for (size_t i = 0; i < contents.size(); i++) {
+ if (contents[i] == seed) {
offsets.push_back(i);
}
}
return offsets;
}
-std::string ObjectModel::to_string(int mask) const
-{
+std::string ObjectModel::to_string(int mask) const {
if (!created) {
return "Object does not exist";
}
return result;
}
-bool ObjectModel::readyForIoOp(IoOp& op)
-{
- return true;
-}
-
-void ObjectModel::applyIoOp(IoOp& op)
-{
- auto generate_random = [&rng = rng]()
- {
- return rng();
- };
-
- auto verify_and_record_read_op = [ &contents = contents,
- &created = created,
- &num_io = num_io,
- &reads = reads,
- &writes = writes ]
- <OpType opType, int N>
- (ReadWriteOp<opType, N>& readOp)
- {
- ceph_assert(created);
- for (int i = 0; i < N; i++)
- {
- ceph_assert(readOp.offset[i] + readOp.length[i] <= contents.size());
- // Not allowed: read overlapping with parallel write
- ceph_assert(!writes.intersects(readOp.offset[i], readOp.length[i]));
- reads.union_insert(readOp.offset[i], readOp.length[i]);
- }
- num_io++;
- };
-
- auto verify_write_and_record_and_generate_seed = [ &generate_random,
- &contents = contents,
- &created = created,
- &num_io = num_io,
- &reads = reads,
- &writes = writes ]
- <OpType opType, int N>
- (ReadWriteOp<opType, N> writeOp)
- {
- ceph_assert(created);
- for (int i = 0; i < N; i++)
- {
- // Not allowed: write overlapping with parallel read or write
- ceph_assert(!reads.intersects(writeOp.offset[i], writeOp.length[i]));
- ceph_assert(!writes.intersects(writeOp.offset[i], writeOp.length[i]));
- writes.union_insert(writeOp.offset[i], writeOp.length[i]);
- ceph_assert(writeOp.offset[i] + writeOp.length[i] <= contents.size());
- std::generate(std::execution::seq,
- std::next(contents.begin(), writeOp.offset[i]),
- std::next(contents.begin(), writeOp.offset[i] + writeOp.length[i]),
- generate_random);
- }
- num_io++;
- };
-
- auto verify_failed_write_and_record = [ &contents = contents,
- &created = created,
- &num_io = num_io,
- &reads = reads,
- &writes = writes ]
- <OpType opType, int N>
- (ReadWriteOp<opType, N> writeOp)
- {
- // Ensure write should still be valid, even though we are expecting OSD failure
- ceph_assert(created);
- for (int i = 0; i < N; i++)
- {
- // Not allowed: write overlapping with parallel read or write
- ceph_assert(!reads.intersects(writeOp.offset[i], writeOp.length[i]));
- ceph_assert(!writes.intersects(writeOp.offset[i], writeOp.length[i]));
- writes.union_insert(writeOp.offset[i], writeOp.length[i]);
- ceph_assert(writeOp.offset[i] + writeOp.length[i] <= contents.size());
- }
- num_io++;
- };
+bool ObjectModel::readyForIoOp(IoOp& op) { return true; }
+
+void ObjectModel::applyIoOp(IoOp& op) {
+ auto generate_random = [&rng = rng]() { return rng(); };
+
+ auto verify_and_record_read_op =
+ [&contents = contents, &created = created, &num_io = num_io,
+ &reads = reads,
+ &writes = writes]<OpType opType, int N>(ReadWriteOp<opType, N>& readOp) {
+ ceph_assert(created);
+ for (int i = 0; i < N; i++) {
+ ceph_assert(readOp.offset[i] + readOp.length[i] <= contents.size());
+ // Not allowed: read overlapping with parallel write
+ ceph_assert(!writes.intersects(readOp.offset[i], readOp.length[i]));
+ reads.union_insert(readOp.offset[i], readOp.length[i]);
+ }
+ num_io++;
+ };
+
+ auto verify_write_and_record_and_generate_seed =
+ [&generate_random, &contents = contents, &created = created,
+ &num_io = num_io, &reads = reads,
+ &writes = writes]<OpType opType, int N>(ReadWriteOp<opType, N> writeOp) {
+ ceph_assert(created);
+ for (int i = 0; i < N; i++) {
+ // Not allowed: write overlapping with parallel read or write
+ ceph_assert(!reads.intersects(writeOp.offset[i], writeOp.length[i]));
+ ceph_assert(!writes.intersects(writeOp.offset[i], writeOp.length[i]));
+ writes.union_insert(writeOp.offset[i], writeOp.length[i]);
+ ceph_assert(writeOp.offset[i] + writeOp.length[i] <= contents.size());
+ std::generate(std::execution::seq,
+ std::next(contents.begin(), writeOp.offset[i]),
+ std::next(contents.begin(),
+ writeOp.offset[i] + writeOp.length[i]),
+ generate_random);
+ }
+ num_io++;
+ };
+
+ auto verify_failed_write_and_record =
+ [&contents = contents, &created = created, &num_io = num_io,
+ &reads = reads,
+ &writes = writes]<OpType opType, int N>(ReadWriteOp<opType, N> writeOp) {
+ // Ensure write should still be valid, even though we are expecting OSD
+ // failure
+ ceph_assert(created);
+ for (int i = 0; i < N; i++) {
+ // Not allowed: write overlapping with parallel read or write
+ ceph_assert(!reads.intersects(writeOp.offset[i], writeOp.length[i]));
+ ceph_assert(!writes.intersects(writeOp.offset[i], writeOp.length[i]));
+ writes.union_insert(writeOp.offset[i], writeOp.length[i]);
+ ceph_assert(writeOp.offset[i] + writeOp.length[i] <= contents.size());
+ }
+ num_io++;
+ };
switch (op.getOpType()) {
- case OpType::Barrier:
- reads.clear();
- writes.clear();
- break;
-
- case OpType::Create:
- ceph_assert(!created);
- ceph_assert(reads.empty());
- ceph_assert(writes.empty());
- created = true;
- contents.resize(static_cast<CreateOp&>(op).size);
- std::generate(std::execution::seq, contents.begin(), contents.end(),
- generate_random);
- break;
-
- case OpType::Remove:
- ceph_assert(created);
- ceph_assert(reads.empty());
- ceph_assert(writes.empty());
- created = false;
- contents.resize(0);
- break;
-
- case OpType::Read:
- {
- SingleReadOp& readOp = static_cast<SingleReadOp&>(op);
- verify_and_record_read_op(readOp);
- }
- break;
- case OpType::Read2:
- {
- DoubleReadOp& readOp = static_cast<DoubleReadOp&>(op);
- verify_and_record_read_op(readOp);
- }
- break;
- case OpType::Read3:
- {
- TripleReadOp& readOp = static_cast<TripleReadOp&>(op);
- verify_and_record_read_op(readOp);
- }
- break;
-
- case OpType::Write:
- {
- ceph_assert(created);
- SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
- verify_write_and_record_and_generate_seed(writeOp);
- }
- break;
- case OpType::Write2:
- {
- DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
- verify_write_and_record_and_generate_seed(writeOp);
- }
- break;
- case OpType::Write3:
- {
- TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
- verify_write_and_record_and_generate_seed(writeOp);
- }
- break;
- case OpType::FailedWrite:
- {
- ceph_assert(created);
- SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
- verify_failed_write_and_record(writeOp);
- }
- break;
- case OpType::FailedWrite2:
- {
- DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
- verify_failed_write_and_record(writeOp);
- }
- break;
- case OpType::FailedWrite3:
- {
- TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
- verify_failed_write_and_record(writeOp);
- }
- break;
- default:
- break;
+ case OpType::Barrier:
+ reads.clear();
+ writes.clear();
+ break;
+
+ case OpType::Create:
+ ceph_assert(!created);
+ ceph_assert(reads.empty());
+ ceph_assert(writes.empty());
+ created = true;
+ contents.resize(static_cast<CreateOp&>(op).size);
+ std::generate(std::execution::seq, contents.begin(), contents.end(),
+ generate_random);
+ break;
+
+ case OpType::Remove:
+ ceph_assert(created);
+ ceph_assert(reads.empty());
+ ceph_assert(writes.empty());
+ created = false;
+ contents.resize(0);
+ break;
+
+ case OpType::Read: {
+ SingleReadOp& readOp = static_cast<SingleReadOp&>(op);
+ verify_and_record_read_op(readOp);
+ } break;
+ case OpType::Read2: {
+ DoubleReadOp& readOp = static_cast<DoubleReadOp&>(op);
+ verify_and_record_read_op(readOp);
+ } break;
+ case OpType::Read3: {
+ TripleReadOp& readOp = static_cast<TripleReadOp&>(op);
+ verify_and_record_read_op(readOp);
+ } break;
+
+ case OpType::Write: {
+ ceph_assert(created);
+ SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
+ verify_write_and_record_and_generate_seed(writeOp);
+ } break;
+ case OpType::Write2: {
+ DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
+ verify_write_and_record_and_generate_seed(writeOp);
+ } break;
+ case OpType::Write3: {
+ TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
+ verify_write_and_record_and_generate_seed(writeOp);
+ } break;
+ case OpType::FailedWrite: {
+ ceph_assert(created);
+ SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
+ verify_failed_write_and_record(writeOp);
+ } break;
+ case OpType::FailedWrite2: {
+ DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
+ verify_failed_write_and_record(writeOp);
+ } break;
+ case OpType::FailedWrite3: {
+ TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
+ verify_failed_write_and_record(writeOp);
+ } break;
+ default:
+ break;
}
}
*/
namespace ceph {
- namespace io_exerciser {
- /* Model of an object to track its data contents */
-
- class ObjectModel : public Model {
- private:
- bool created;
- std::vector<int> contents;
- ceph::util::random_number_generator<int> rng =
- ceph::util::random_number_generator<int>();
-
- // Track read and write I/Os that can be submitted in
- // parallel to detect violations:
- //
- // * Read may not overlap with a parallel write
- // * Write may not overlap with a parallel read or write
- // * Create / remove may not be in parallel with read or write
- //
- // Fix broken test cases by adding barrier ops to restrict
- // I/O exercisers from issuing conflicting ops in parallel
- interval_set<uint64_t> reads;
- interval_set<uint64_t> writes;
- public:
- ObjectModel(const std::string& oid, uint64_t block_size, int seed);
-
- int get_seed(uint64_t offset) const;
- std::vector<int> get_seed_offsets(int seed) const;
-
- std::string to_string(int mask = -1) const;
-
- bool readyForIoOp(IoOp& op);
- void applyIoOp(IoOp& op);
-
- void encode(ceph::buffer::list& bl) const;
- void decode(ceph::buffer::list::const_iterator& bl);
- };
- }
-}
\ No newline at end of file
+namespace io_exerciser {
+/* Model of an object to track its data contents */
+
+class ObjectModel : public Model {
+ private:
+ bool created;
+ std::vector<int> contents;
+ ceph::util::random_number_generator<int> rng =
+ ceph::util::random_number_generator<int>();
+
+ // Track read and write I/Os that can be submitted in
+ // parallel to detect violations:
+ //
+ // * Read may not overlap with a parallel write
+ // * Write may not overlap with a parallel read or write
+ // * Create / remove may not be in parallel with read or write
+ //
+ // Fix broken test cases by adding barrier ops to restrict
+ // I/O exercisers from issuing conflicting ops in parallel
+ interval_set<uint64_t> reads;
+ interval_set<uint64_t> writes;
+
+ public:
+ ObjectModel(const std::string& oid, uint64_t block_size, int seed);
+
+ int get_seed(uint64_t offset) const;
+ std::vector<int> get_seed_offsets(int seed) const;
+
+ std::string to_string(int mask = -1) const;
+
+ bool readyForIoOp(IoOp& op);
+ void applyIoOp(IoOp& op);
+
+ void encode(ceph::buffer::list& bl) const;
+ void decode(ceph::buffer::list::const_iterator& bl);
+};
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
#pragma once
#include <fmt/format.h>
-
#include <include/ceph_assert.h>
/* Overview
*
*/
-namespace ceph
-{
- namespace io_exerciser
- {
- enum class OpType
- {
- Done, // End of I/O sequence
- Barrier, // Barrier - all prior I/Os must complete
- Create, // Create object and pattern with data
- Remove, // Remove object
- Read, // Read
- Read2, // Two reads in a single op
- Read3, // Three reads in a single op
- Write, // Write
- Write2, // Two writes in a single op
- Write3, // Three writes in a single op
- FailedWrite, // A write which should fail
- FailedWrite2, // Two writes in one op which should fail
- FailedWrite3, // Three writes in one op which should fail
- InjectReadError, // Op to tell OSD to inject read errors
- InjectWriteError, // Op to tell OSD to inject write errors
- ClearReadErrorInject, // Op to tell OSD to clear read error injects
- ClearWriteErrorInject // Op to tell OSD to clear write error injects
- };
+namespace ceph {
+namespace io_exerciser {
+enum class OpType {
+ Done, // End of I/O sequence
+ Barrier, // Barrier - all prior I/Os must complete
+ Create, // Create object and pattern with data
+ Remove, // Remove object
+ Read, // Read
+ Read2, // Two reads in a single op
+ Read3, // Three reads in a single op
+ Write, // Write
+ Write2, // Two writes in a single op
+ Write3, // Three writes in a single op
+ FailedWrite, // A write which should fail
+ FailedWrite2, // Two writes in one op which should fail
+ FailedWrite3, // Three writes in one op which should fail
+ InjectReadError, // Op to tell OSD to inject read errors
+ InjectWriteError, // Op to tell OSD to inject write errors
+ ClearReadErrorInject, // Op to tell OSD to clear read error injects
+ ClearWriteErrorInject // Op to tell OSD to clear write error injects
+};
- enum class InjectOpType {
- None,
- ReadEIO,
- ReadMissingShard,
- WriteFailAndRollback,
- WriteOSDAbort
- };
- }
-}
+enum class InjectOpType {
+ None,
+ ReadEIO,
+ ReadMissingShard,
+ WriteFailAndRollback,
+ WriteOSDAbort
+};
+} // namespace io_exerciser
+} // namespace ceph
template <>
-struct fmt::formatter<ceph::io_exerciser::OpType>
-{
- constexpr auto parse(format_parse_context& ctx)
- {
- return ctx.begin();
- }
+struct fmt::formatter<ceph::io_exerciser::OpType> {
+ constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
- auto format(ceph::io_exerciser::OpType opType, fmt::format_context& ctx) const -> fmt::format_context::iterator
- {
- switch (opType)
- {
+ auto format(ceph::io_exerciser::OpType opType,
+ fmt::format_context& ctx) const -> fmt::format_context::iterator {
+ switch (opType) {
case ceph::io_exerciser::OpType::Done:
return fmt::format_to(ctx.out(), "Done");
case ceph::io_exerciser::OpType::Barrier:
#include "RadosIo.h"
-#include "DataGenerator.h"
-
#include <fmt/format.h>
#include <json_spirit/json_spirit.h>
-#include "common/ceph_json.h"
+#include <ranges>
+#include "DataGenerator.h"
#include "JsonStructures.h"
-
-#include <ranges>
+#include "common/ceph_json.h"
using RadosIo = ceph::io_exerciser::RadosIo;
-RadosIo::RadosIo(librados::Rados& rados,
- boost::asio::io_context& asio,
- const std::string& pool,
- const std::string& oid,
- const std::optional<std::vector<int>>& cached_shard_order,
- uint64_t block_size,
- int seed,
- int threads,
- ceph::mutex& lock,
- ceph::condition_variable& cond) :
- Model(oid, block_size),
- rados(rados),
- asio(asio),
- om(std::make_unique<ObjectModel>(oid, block_size, seed)),
- db(data_generation::DataGenerator::create_generator(
- data_generation::GenerationType::HeaderedSeededRandom, *om)),
- pool(pool),
- cached_shard_order(cached_shard_order),
- threads(threads),
- lock(lock),
- cond(cond),
- outstanding_io(0)
-{
+RadosIo::RadosIo(librados::Rados& rados, boost::asio::io_context& asio,
+ const std::string& pool, const std::string& oid,
+ const std::optional<std::vector<int>>& cached_shard_order,
+ uint64_t block_size, int seed, int threads, ceph::mutex& lock,
+ ceph::condition_variable& cond)
+ : Model(oid, block_size),
+ rados(rados),
+ asio(asio),
+ om(std::make_unique<ObjectModel>(oid, block_size, seed)),
+ db(data_generation::DataGenerator::create_generator(
+ data_generation::GenerationType::HeaderedSeededRandom, *om)),
+ pool(pool),
+ cached_shard_order(cached_shard_order),
+ threads(threads),
+ lock(lock),
+ cond(cond),
+ outstanding_io(0) {
int rc;
rc = rados.ioctx_create(pool.c_str(), io);
ceph_assert(rc == 0);
allow_ec_overwrites(true);
}
-RadosIo::~RadosIo()
-{
-}
+RadosIo::~RadosIo() {}
-void RadosIo::start_io()
-{
+void RadosIo::start_io() {
std::lock_guard l(lock);
outstanding_io++;
}
-void RadosIo::finish_io()
-{
+void RadosIo::finish_io() {
std::lock_guard l(lock);
ceph_assert(outstanding_io > 0);
outstanding_io--;
cond.notify_all();
}
-void RadosIo::wait_for_io(int count)
-{
+void RadosIo::wait_for_io(int count) {
std::unique_lock l(lock);
while (outstanding_io > count) {
cond.wait(l);
}
}
-void RadosIo::allow_ec_overwrites(bool allow)
-{
+void RadosIo::allow_ec_overwrites(bool allow) {
int rc;
bufferlist inbl, outbl;
- std::string cmdstr =
- "{\"prefix\": \"osd pool set\", \"pool\": \"" + pool + "\", \
+ std::string cmdstr = "{\"prefix\": \"osd pool set\", \"pool\": \"" + pool +
+ "\", \
\"var\": \"allow_ec_overwrites\", \"val\": \"" +
- (allow ? "true" : "false") + "\"}";
+ (allow ? "true" : "false") + "\"}";
rc = rados.mon_command(cmdstr, inbl, &outbl, nullptr);
ceph_assert(rc == 0);
}
template <int N>
RadosIo::AsyncOpInfo<N>::AsyncOpInfo(const std::array<uint64_t, N>& offset,
- const std::array<uint64_t, N>& length) :
- offset(offset), length(length)
-{
-
-}
+ const std::array<uint64_t, N>& length)
+ : offset(offset), length(length) {}
-bool RadosIo::readyForIoOp(IoOp &op)
-{
- ceph_assert(ceph_mutex_is_locked_by_me(lock)); //Must be called with lock held
- if (!om->readyForIoOp(op))
- {
+bool RadosIo::readyForIoOp(IoOp& op) {
+ ceph_assert(
+ ceph_mutex_is_locked_by_me(lock)); // Must be called with lock held
+ if (!om->readyForIoOp(op)) {
return false;
}
- switch (op.getOpType())
- {
- case OpType::Done:
- case OpType::Barrier:
- return outstanding_io == 0;
- default:
- return outstanding_io < threads;
+ switch (op.getOpType()) {
+ case OpType::Done:
+ case OpType::Barrier:
+ return outstanding_io == 0;
+ default:
+ return outstanding_io < threads;
}
}
-void RadosIo::applyIoOp(IoOp& op)
-{
+void RadosIo::applyIoOp(IoOp& op) {
om->applyIoOp(op);
// If there are thread concurrent I/Os in flight then wait for
// at least one I/O to complete
- wait_for_io(threads-1);
-
- switch (op.getOpType())
- {
- case OpType::Done:
- [[ fallthrough ]];
- case OpType::Barrier:
- // Wait for all outstanding I/O to complete
- wait_for_io(0);
- break;
-
- case OpType::Create:
- {
- start_io();
- uint64_t opSize = static_cast<CreateOp&>(op).size;
- std::shared_ptr<AsyncOpInfo<1>> op_info
- = std::make_shared<AsyncOpInfo<1>>(std::array<uint64_t,1>{0},
- std::array<uint64_t,1>{opSize});
- op_info->bufferlist[0] = db->generate_data(0, opSize);
- op_info->wop.write_full(op_info->bufferlist[0]);
- auto create_cb = [this](boost::system::error_code ec,
- version_t ver)
- {
- ceph_assert(ec == boost::system::errc::success);
- finish_io();
- };
- librados::async_operate(asio, io, oid,
- &op_info->wop, 0, nullptr, create_cb);
- break;
- }
+ wait_for_io(threads - 1);
+
+ switch (op.getOpType()) {
+ case OpType::Done:
+ [[fallthrough]];
+ case OpType::Barrier:
+ // Wait for all outstanding I/O to complete
+ wait_for_io(0);
+ break;
- case OpType::Remove:
- {
- start_io();
- auto op_info = std::make_shared<AsyncOpInfo<0>>();
- op_info->wop.remove();
- auto remove_cb = [this] (boost::system::error_code ec,
- version_t ver)
- {
- ceph_assert(ec == boost::system::errc::success);
- finish_io();
- };
- librados::async_operate(asio, io, oid,
- &op_info->wop, 0, nullptr, remove_cb);
- break;
- }
- case OpType::Read:
- [[ fallthrough ]];
- case OpType::Read2:
- [[ fallthrough ]];
- case OpType::Read3:
- [[ fallthrough ]];
- case OpType::Write:
- [[ fallthrough ]];
- case OpType::Write2:
- [[ fallthrough ]];
- case OpType::Write3:
- [[ fallthrough ]];
- case OpType::FailedWrite:
- [[ fallthrough ]];
- case OpType::FailedWrite2:
- [[ fallthrough ]];
- case OpType::FailedWrite3:
- applyReadWriteOp(op);
- break;
- case OpType::InjectReadError:
- [[ fallthrough ]];
- case OpType::InjectWriteError:
- [[ fallthrough ]];
- case OpType::ClearReadErrorInject:
- [[ fallthrough ]];
- case OpType::ClearWriteErrorInject:
- applyInjectOp(op);
- break;
- default:
- ceph_abort_msg("Unrecognised Op");
- break;
+ case OpType::Create: {
+ start_io();
+ uint64_t opSize = static_cast<CreateOp&>(op).size;
+ std::shared_ptr<AsyncOpInfo<1>> op_info =
+ std::make_shared<AsyncOpInfo<1>>(std::array<uint64_t, 1>{0},
+ std::array<uint64_t, 1>{opSize});
+ op_info->bufferlist[0] = db->generate_data(0, opSize);
+ op_info->wop.write_full(op_info->bufferlist[0]);
+ auto create_cb = [this](boost::system::error_code ec, version_t ver) {
+ ceph_assert(ec == boost::system::errc::success);
+ finish_io();
+ };
+ librados::async_operate(asio, io, oid, &op_info->wop, 0, nullptr,
+ create_cb);
+ break;
+ }
+
+ case OpType::Remove: {
+ start_io();
+ auto op_info = std::make_shared<AsyncOpInfo<0>>();
+ op_info->wop.remove();
+ auto remove_cb = [this](boost::system::error_code ec, version_t ver) {
+ ceph_assert(ec == boost::system::errc::success);
+ finish_io();
+ };
+ librados::async_operate(asio, io, oid, &op_info->wop, 0, nullptr,
+ remove_cb);
+ break;
+ }
+ case OpType::Read:
+ [[fallthrough]];
+ case OpType::Read2:
+ [[fallthrough]];
+ case OpType::Read3:
+ [[fallthrough]];
+ case OpType::Write:
+ [[fallthrough]];
+ case OpType::Write2:
+ [[fallthrough]];
+ case OpType::Write3:
+ [[fallthrough]];
+ case OpType::FailedWrite:
+ [[fallthrough]];
+ case OpType::FailedWrite2:
+ [[fallthrough]];
+ case OpType::FailedWrite3:
+ applyReadWriteOp(op);
+ break;
+ case OpType::InjectReadError:
+ [[fallthrough]];
+ case OpType::InjectWriteError:
+ [[fallthrough]];
+ case OpType::ClearReadErrorInject:
+ [[fallthrough]];
+ case OpType::ClearWriteErrorInject:
+ applyInjectOp(op);
+ break;
+ default:
+ ceph_abort_msg("Unrecognised Op");
+ break;
}
}
-void RadosIo::applyReadWriteOp(IoOp& op)
-{
- auto applyReadOp = [this]<OpType opType, int N>(ReadWriteOp<opType, N> readOp)
- {
- auto op_info = std::make_shared<AsyncOpInfo<N>>(readOp.offset, readOp.length);
+void RadosIo::applyReadWriteOp(IoOp& op) {
+ auto applyReadOp = [this]<OpType opType, int N>(
+ ReadWriteOp<opType, N> readOp) {
+ auto op_info =
+ std::make_shared<AsyncOpInfo<N>>(readOp.offset, readOp.length);
- for (int i = 0; i < N; i++)
- {
+ for (int i = 0; i < N; i++) {
op_info->rop.read(readOp.offset[i] * block_size,
- readOp.length[i] * block_size,
- &op_info->bufferlist[i], nullptr);
+ readOp.length[i] * block_size, &op_info->bufferlist[i],
+ nullptr);
}
- auto read_cb = [this, op_info] (boost::system::error_code ec,
- version_t ver,
- bufferlist bl)
- {
+ auto read_cb = [this, op_info](boost::system::error_code ec, version_t ver,
+ bufferlist bl) {
ceph_assert(ec == boost::system::errc::success);
- for (int i = 0; i < N; i++)
- {
- ceph_assert(db->validate(op_info->bufferlist[i],
- op_info->offset[i],
- op_info->length[i]));
+ for (int i = 0; i < N; i++) {
+ ceph_assert(db->validate(op_info->bufferlist[i], op_info->offset[i],
+ op_info->length[i]));
}
finish_io();
};
- librados::async_operate(asio, io, oid,
- &op_info->rop, 0, nullptr, read_cb);
+ librados::async_operate(asio, io, oid, &op_info->rop, 0, nullptr, read_cb);
num_io++;
};
- auto applyWriteOp = [this]<OpType opType, int N>(ReadWriteOp<opType, N> writeOp)
- {
- auto op_info = std::make_shared<AsyncOpInfo<N>>(writeOp.offset, writeOp.length);
- for (int i = 0; i < N; i++)
- {
- op_info->bufferlist[i] = db->generate_data(writeOp.offset[i], writeOp.length[i]);
- op_info->wop.write(writeOp.offset[i] * block_size, op_info->bufferlist[i]);
+ auto applyWriteOp = [this]<OpType opType, int N>(
+ ReadWriteOp<opType, N> writeOp) {
+ auto op_info =
+ std::make_shared<AsyncOpInfo<N>>(writeOp.offset, writeOp.length);
+ for (int i = 0; i < N; i++) {
+ op_info->bufferlist[i] =
+ db->generate_data(writeOp.offset[i], writeOp.length[i]);
+ op_info->wop.write(writeOp.offset[i] * block_size,
+ op_info->bufferlist[i]);
}
- auto write_cb = [this] (boost::system::error_code ec,
- version_t ver)
- {
+ auto write_cb = [this](boost::system::error_code ec, version_t ver) {
ceph_assert(ec == boost::system::errc::success);
finish_io();
};
- librados::async_operate(asio, io, oid,
- &op_info->wop, 0, nullptr, write_cb);
+ librados::async_operate(asio, io, oid, &op_info->wop, 0, nullptr, write_cb);
num_io++;
};
- auto applyFailedWriteOp = [this]<OpType opType, int N>(ReadWriteOp<opType, N> writeOp)
- {
- auto op_info = std::make_shared<AsyncOpInfo<N>>(writeOp.offset, writeOp.length);
- for (int i = 0; i < N; i++)
- {
- op_info->bufferlist[i] = db->generate_data(writeOp.offset[i], writeOp.length[i]);
- op_info->wop.write(writeOp.offset[i] * block_size, op_info->bufferlist[i]);
+ auto applyFailedWriteOp = [this]<OpType opType, int N>(
+ ReadWriteOp<opType, N> writeOp) {
+ auto op_info =
+ std::make_shared<AsyncOpInfo<N>>(writeOp.offset, writeOp.length);
+ for (int i = 0; i < N; i++) {
+ op_info->bufferlist[i] =
+ db->generate_data(writeOp.offset[i], writeOp.length[i]);
+ op_info->wop.write(writeOp.offset[i] * block_size,
+ op_info->bufferlist[i]);
}
- auto write_cb = [this, writeOp] (boost::system::error_code ec,
- version_t ver)
- {
+ auto write_cb = [this, writeOp](boost::system::error_code ec,
+ version_t ver) {
ceph_assert(ec != boost::system::errc::success);
finish_io();
};
- librados::async_operate(asio, io, oid,
- &op_info->wop, 0, nullptr, write_cb);
+ librados::async_operate(asio, io, oid, &op_info->wop, 0, nullptr, write_cb);
num_io++;
};
- switch (op.getOpType())
- {
- case OpType::Read:
- {
+ switch (op.getOpType()) {
+ case OpType::Read: {
start_io();
SingleReadOp& readOp = static_cast<SingleReadOp&>(op);
applyReadOp(readOp);
break;
- }
- case OpType::Read2:
- {
- start_io();
- DoubleReadOp& readOp = static_cast<DoubleReadOp&>(op);
- applyReadOp(readOp);
- break;
- }
- case OpType::Read3:
- {
- start_io();
- TripleReadOp& readOp = static_cast<TripleReadOp&>(op);
- applyReadOp(readOp);
- break;
- }
- case OpType::Write:
- {
- start_io();
- SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
- applyWriteOp(writeOp);
- break;
- }
- case OpType::Write2:
- {
- start_io();
- DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
- applyWriteOp(writeOp);
- break;
- }
- case OpType::Write3:
- {
- start_io();
- TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
- applyWriteOp(writeOp);
- break;
- }
+ }
+ case OpType::Read2: {
+ start_io();
+ DoubleReadOp& readOp = static_cast<DoubleReadOp&>(op);
+ applyReadOp(readOp);
+ break;
+ }
+ case OpType::Read3: {
+ start_io();
+ TripleReadOp& readOp = static_cast<TripleReadOp&>(op);
+ applyReadOp(readOp);
+ break;
+ }
+ case OpType::Write: {
+ start_io();
+ SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
+ applyWriteOp(writeOp);
+ break;
+ }
+ case OpType::Write2: {
+ start_io();
+ DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
+ applyWriteOp(writeOp);
+ break;
+ }
+ case OpType::Write3: {
+ start_io();
+ TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
+ applyWriteOp(writeOp);
+ break;
+ }
- case OpType::FailedWrite:
- {
- start_io();
- SingleFailedWriteOp& writeOp = static_cast<SingleFailedWriteOp&>(op);
- applyFailedWriteOp(writeOp);
- break;
- }
- case OpType::FailedWrite2:
- {
- start_io();
- DoubleFailedWriteOp& writeOp = static_cast<DoubleFailedWriteOp&>(op);
- applyFailedWriteOp(writeOp);
- break;
- }
- case OpType::FailedWrite3:
- {
- start_io();
- TripleFailedWriteOp& writeOp = static_cast<TripleFailedWriteOp&>(op);
- applyFailedWriteOp(writeOp);
- break;
- }
+ case OpType::FailedWrite: {
+ start_io();
+ SingleFailedWriteOp& writeOp = static_cast<SingleFailedWriteOp&>(op);
+ applyFailedWriteOp(writeOp);
+ break;
+ }
+ case OpType::FailedWrite2: {
+ start_io();
+ DoubleFailedWriteOp& writeOp = static_cast<DoubleFailedWriteOp&>(op);
+ applyFailedWriteOp(writeOp);
+ break;
+ }
+ case OpType::FailedWrite3: {
+ start_io();
+ TripleFailedWriteOp& writeOp = static_cast<TripleFailedWriteOp&>(op);
+ applyFailedWriteOp(writeOp);
+ break;
+ }
- default:
- ceph_abort_msg(fmt::format("Unsupported Read/Write operation ({})",
- op.getOpType()));
- break;
+ default:
+ ceph_abort_msg(
+ fmt::format("Unsupported Read/Write operation ({})", op.getOpType()));
+ break;
}
}
-void RadosIo::applyInjectOp(IoOp& op)
-{
+void RadosIo::applyInjectOp(IoOp& op) {
bufferlist osdmap_inbl, inject_inbl, osdmap_outbl, inject_outbl;
auto formatter = std::make_shared<JSONFormatter>(false);
int osd = -1;
std::vector<int> shard_order;
- ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool,
- get_oid(),
- "",
+ ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, get_oid(), "",
formatter);
- int rc = rados.mon_command(osdMapRequest.encode_json(),
- osdmap_inbl,
- &osdmap_outbl,
- nullptr);
+ int rc = rados.mon_command(osdMapRequest.encode_json(), osdmap_inbl,
+ &osdmap_outbl, nullptr);
ceph_assert(rc == 0);
JSONParser p;
InjectOpType injectOpType;
- switch(op.getOpType())
- {
- case OpType::InjectReadError:
- {
+ switch (op.getOpType()) {
+ case OpType::InjectReadError: {
InjectReadErrorOp& errorOp = static_cast<InjectReadErrorOp&>(op);
- if (errorOp.type == 0)
- {
+ if (errorOp.type == 0) {
injectOpType = InjectOpType::ReadEIO;
- }
- else if (errorOp.type == 1)
- {
+ } else if (errorOp.type == 1) {
injectOpType = InjectOpType::ReadMissingShard;
- }
- else
- {
+ } else {
ceph_abort_msg("Unsupported inject type");
}
- ceph::io_exerciser::json::InjectECErrorRequest injectErrorRequest(injectOpType,
- pool,
- oid,
- errorOp.shard,
- errorOp.type,
- errorOp.when,
- errorOp.duration,
- formatter);
+ ceph::io_exerciser::json::InjectECErrorRequest injectErrorRequest(
+ injectOpType, pool, oid, errorOp.shard, errorOp.type, errorOp.when,
+ errorOp.duration, formatter);
- int rc = rados.osd_command(osd, injectErrorRequest.encode_json(), inject_inbl, &inject_outbl, nullptr);
+ int rc = rados.osd_command(osd, injectErrorRequest.encode_json(),
+ inject_inbl, &inject_outbl, nullptr);
ceph_assert(rc == 0);
break;
}
- case OpType::InjectWriteError:
- {
+ case OpType::InjectWriteError: {
InjectWriteErrorOp& errorOp = static_cast<InjectWriteErrorOp&>(op);
- if (errorOp.type == 0)
- {
+ if (errorOp.type == 0) {
injectOpType = InjectOpType::WriteFailAndRollback;
- }
- else if (errorOp.type == 3)
- {
+ } else if (errorOp.type == 3) {
injectOpType = InjectOpType::WriteOSDAbort;
- // This inject is sent directly to the shard we want to inject the error on
+ // This inject is sent directly to the shard we want to inject the error
+ // on
osd = shard_order[errorOp.shard];
- }
- else
- {
+ } else {
ceph_abort("Unsupported inject type");
}
- ceph::io_exerciser::json::InjectECErrorRequest injectErrorRequest(injectOpType,
- pool,
- oid,
- errorOp.shard,
- errorOp.type,
- errorOp.when,
- errorOp.duration,
- formatter);
+ ceph::io_exerciser::json::InjectECErrorRequest injectErrorRequest(
+ injectOpType, pool, oid, errorOp.shard, errorOp.type, errorOp.when,
+ errorOp.duration, formatter);
- int rc = rados.osd_command(osd, injectErrorRequest.encode_json(), inject_inbl, &inject_outbl, nullptr);
+ int rc = rados.osd_command(osd, injectErrorRequest.encode_json(),
+ inject_inbl, &inject_outbl, nullptr);
ceph_assert(rc == 0);
break;
}
- case OpType::ClearReadErrorInject:
- {
- ClearReadErrorInjectOp& errorOp = static_cast<ClearReadErrorInjectOp&>(op);
+ case OpType::ClearReadErrorInject: {
+ ClearReadErrorInjectOp& errorOp =
+ static_cast<ClearReadErrorInjectOp&>(op);
- if (errorOp.type == 0)
- {
+ if (errorOp.type == 0) {
injectOpType = InjectOpType::ReadEIO;
- }
- else if (errorOp.type == 1)
- {
+ } else if (errorOp.type == 1) {
injectOpType = InjectOpType::ReadMissingShard;
- }
- else
- {
+ } else {
ceph_abort("Unsupported inject type");
}
- ceph::io_exerciser::json::InjectECClearErrorRequest clearErrorInject(injectOpType,
- pool,
- oid,
- errorOp.shard,
- errorOp.type);
+ ceph::io_exerciser::json::InjectECClearErrorRequest clearErrorInject(
+ injectOpType, pool, oid, errorOp.shard, errorOp.type);
- int rc = rados.osd_command(osd, clearErrorInject.encode_json(), inject_inbl, &inject_outbl, nullptr);
+ int rc = rados.osd_command(osd, clearErrorInject.encode_json(),
+ inject_inbl, &inject_outbl, nullptr);
ceph_assert(rc == 0);
break;
}
- case OpType::ClearWriteErrorInject:
- {
- ClearReadErrorInjectOp& errorOp = static_cast<ClearReadErrorInjectOp&>(op);
+ case OpType::ClearWriteErrorInject: {
+ ClearReadErrorInjectOp& errorOp =
+ static_cast<ClearReadErrorInjectOp&>(op);
- if (errorOp.type == 0)
- {
+ if (errorOp.type == 0) {
injectOpType = InjectOpType::WriteFailAndRollback;
- }
- else if (errorOp.type == 3)
- {
+ } else if (errorOp.type == 3) {
injectOpType = InjectOpType::WriteOSDAbort;
- }
- else
- {
+ } else {
ceph_abort("Unsupported inject type");
}
- ceph::io_exerciser::json::InjectECClearErrorRequest clearErrorInject(injectOpType,
- pool,
- oid,
- errorOp.shard,
- errorOp.type);
+ ceph::io_exerciser::json::InjectECClearErrorRequest clearErrorInject(
+ injectOpType, pool, oid, errorOp.shard, errorOp.type);
- int rc = rados.osd_command(osd, clearErrorInject.encode_json(), inject_inbl, &inject_outbl, nullptr);
+ int rc = rados.osd_command(osd, clearErrorInject.encode_json(),
+ inject_inbl, &inject_outbl, nullptr);
ceph_assert(rc == 0);
break;
}
default:
- ceph_abort_msg(fmt::format("Unsupported inject operation ({})", op.getOpType()));
+ ceph_abort_msg(
+ fmt::format("Unsupported inject operation ({})", op.getOpType()));
break;
}
}
\ No newline at end of file
* in the object. Uses DataBuffer to create and validate
* data buffers. When there are not barrier I/Os this may
* issue multiple async I/Os in parallel.
- *
+ *
*/
namespace ceph {
- namespace io_exerciser {
- namespace data_generation {
- class DataGenerator;
- }
+namespace io_exerciser {
+namespace data_generation {
+class DataGenerator;
+}
- class RadosIo: public Model {
- protected:
- librados::Rados& rados;
- boost::asio::io_context& asio;
- std::unique_ptr<ObjectModel> om;
- std::unique_ptr<ceph::io_exerciser::data_generation::DataGenerator> db;
- std::string pool;
- std::optional<std::vector<int>> cached_shard_order;
- int threads;
- ceph::mutex& lock;
- ceph::condition_variable& cond;
- librados::IoCtx io;
- int outstanding_io;
+class RadosIo : public Model {
+ protected:
+ librados::Rados& rados;
+ boost::asio::io_context& asio;
+ std::unique_ptr<ObjectModel> om;
+ std::unique_ptr<ceph::io_exerciser::data_generation::DataGenerator> db;
+ std::string pool;
+ std::optional<std::vector<int>> cached_shard_order;
+ int threads;
+ ceph::mutex& lock;
+ ceph::condition_variable& cond;
+ librados::IoCtx io;
+ int outstanding_io;
- void start_io();
- void finish_io();
- void wait_for_io(int count);
+ void start_io();
+ void finish_io();
+ void wait_for_io(int count);
- public:
- RadosIo(librados::Rados& rados,
- boost::asio::io_context& asio,
- const std::string& pool,
- const std::string& oid,
- const std::optional<std::vector<int>>& cached_shard_order,
- uint64_t block_size,
- int seed,
- int threads,
- ceph::mutex& lock,
- ceph::condition_variable& cond);
+ public:
+ RadosIo(librados::Rados& rados, boost::asio::io_context& asio,
+ const std::string& pool, const std::string& oid,
+ const std::optional<std::vector<int>>& cached_shard_order,
+ uint64_t block_size, int seed, int threads, ceph::mutex& lock,
+ ceph::condition_variable& cond);
- ~RadosIo();
+ ~RadosIo();
- void allow_ec_overwrites(bool allow);
+ void allow_ec_overwrites(bool allow);
- template <int N>
- class AsyncOpInfo {
- public:
- librados::ObjectReadOperation rop;
- librados::ObjectWriteOperation wop;
- std::array<ceph::bufferlist, N> bufferlist;
- std::array<uint64_t, N> offset;
- std::array<uint64_t, N> length;
+ template <int N>
+ class AsyncOpInfo {
+ public:
+ librados::ObjectReadOperation rop;
+ librados::ObjectWriteOperation wop;
+ std::array<ceph::bufferlist, N> bufferlist;
+ std::array<uint64_t, N> offset;
+ std::array<uint64_t, N> length;
- AsyncOpInfo(const std::array<uint64_t, N>& offset = {},
- const std::array<uint64_t, N>& length = {});
- ~AsyncOpInfo() = default;
- };
+ AsyncOpInfo(const std::array<uint64_t, N>& offset = {},
+ const std::array<uint64_t, N>& length = {});
+ ~AsyncOpInfo() = default;
+ };
- // Must be called with lock held
- bool readyForIoOp(IoOp& op);
- void applyIoOp(IoOp& op);
+ // Must be called with lock held
+ bool readyForIoOp(IoOp& op);
+ void applyIoOp(IoOp& op);
- private:
- void applyReadWriteOp(IoOp& op);
- void applyInjectOp(IoOp& op);
- };
- }
-}
\ No newline at end of file
+ private:
+ void applyReadWriteOp(IoOp& op);
+ void applyInjectOp(IoOp& op);
+};
+} // namespace io_exerciser
+} // namespace ceph
\ No newline at end of file
#include "ceph_test_rados_io_sequence.h"
+#include <boost/asio/io_context.hpp>
#include <iostream>
#include <vector>
-#include <boost/asio/io_context.hpp>
-
-#include "include/random.h"
-
-#include "librados/librados_asio.h"
-#include "common/ceph_argparse.h"
-#include "include/interval_set.h"
-#include "global/global_init.h"
-#include "global/global_context.h"
+#include "common/Formatter.h"
#include "common/Thread.h"
+#include "common/ceph_argparse.h"
+#include "common/ceph_json.h"
#include "common/debug.h"
#include "common/dout.h"
#include "common/split.h"
#include "common/Formatter.h"
#include "common/io_exerciser/DataGenerator.h"
-#include "common/io_exerciser/Model.h"
-#include "common/io_exerciser/ObjectModel.h"
-#include "common/io_exerciser/RadosIo.h"
+#include "common/io_exerciser/EcIoSequence.h"
#include "common/io_exerciser/IoOp.h"
#include "common/io_exerciser/IoSequence.h"
-#include "common/io_exerciser/EcIoSequence.h"
#include "common/io_exerciser/JsonStructures.h"
-
-#include "json_spirit/json_spirit.h"
-
+#include "common/io_exerciser/Model.h"
+#include "common/io_exerciser/ObjectModel.h"
+#include "common/io_exerciser/RadosIo.h"
#include "fmt/format.h"
+#include "global/global_context.h"
+#include "global/global_init.h"
+#include "include/interval_set.h"
+#include "include/random.h"
+#include "json_spirit/json_spirit.h"
+#include "librados/librados_asio.h"
#define dout_subsys ceph_subsys_rados
#define dout_context g_ceph_context
using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
namespace {
- struct Size {};
- void validate(boost::any& v, const std::vector<std::string>& values,
- Size *target_type, int) {
- po::validators::check_first_occurrence(v);
- const std::string &s = po::validators::get_single_string(values);
-
- std::string parse_error;
- uint64_t size = strict_iecstrtoll(s, &parse_error);
- if (!parse_error.empty()) {
- throw po::validation_error(po::validation_error::invalid_option_value);
- }
- v = boost::any(size);
+struct Size {};
+void validate(boost::any& v, const std::vector<std::string>& values,
+ Size* target_type, int) {
+ po::validators::check_first_occurrence(v);
+ const std::string& s = po::validators::get_single_string(values);
+
+ std::string parse_error;
+ uint64_t size = strict_iecstrtoll(s, &parse_error);
+ if (!parse_error.empty()) {
+ throw po::validation_error(po::validation_error::invalid_option_value);
}
+ v = boost::any(size);
+}
- struct Pair {};
- void validate(boost::any& v, const std::vector<std::string>& values,
- Pair *target_type, int) {
- po::validators::check_first_occurrence(v);
- const std::string &s = po::validators::get_single_string(values);
- auto part = ceph::split(s).begin();
- std::string parse_error;
- int first = strict_iecstrtoll(*part++, &parse_error);
- int second = strict_iecstrtoll(*part, &parse_error);
- if (!parse_error.empty()) {
- throw po::validation_error(po::validation_error::invalid_option_value);
- }
- v = boost::any(std::pair<int,int>{first,second});
+struct Pair {};
+void validate(boost::any& v, const std::vector<std::string>& values,
+ Pair* target_type, int) {
+ po::validators::check_first_occurrence(v);
+ const std::string& s = po::validators::get_single_string(values);
+ auto part = ceph::split(s).begin();
+ std::string parse_error;
+ int first = strict_iecstrtoll(*part++, &parse_error);
+ int second = strict_iecstrtoll(*part, &parse_error);
+ if (!parse_error.empty()) {
+ throw po::validation_error(po::validation_error::invalid_option_value);
}
+ v = boost::any(std::pair<int, int>{first, second});
+}
- struct PluginString {};
- void validate(boost::any& v, const std::vector<std::string>& values,
- PluginString *target_type, int) {
- po::validators::check_first_occurrence(v);
- const std::string &s = po::validators::get_single_string(values);
-
- const std::string_view* pluginIt = std::find(
- ceph::io_sequence::tester::pluginChoices.begin(),
- ceph::io_sequence::tester::pluginChoices.end(),
- s
- );
- if(ceph::io_sequence::tester::pluginChoices.end() == pluginIt)
- {
- throw po::validation_error(po::validation_error::invalid_option_value);
- }
+struct PluginString {};
+void validate(boost::any& v, const std::vector<std::string>& values,
+ PluginString* target_type, int) {
+ po::validators::check_first_occurrence(v);
+ const std::string& s = po::validators::get_single_string(values);
- v = boost::any(*pluginIt);
+ const std::string_view* pluginIt =
+ std::find(ceph::io_sequence::tester::pluginChoices.begin(),
+ ceph::io_sequence::tester::pluginChoices.end(), s);
+ if (ceph::io_sequence::tester::pluginChoices.end() == pluginIt) {
+ throw po::validation_error(po::validation_error::invalid_option_value);
}
- constexpr std::string_view usage[] = {
+ v = boost::any(*pluginIt);
+}
+
+constexpr std::string_view usage[] = {
"Basic usage:",
"",
"ceph_test_rados_io_sequence",
"\t\t read3|write3|failedwrite3 <off> <len> <off> <len> <off> <len>",
"\t\t injecterror <type> <shard> <good_count> <fail_count>",
"\t\t clearinject <type> <shard>",
- "\t\t done"
- };
-
- po::options_description get_options_description()
- {
- po::options_description desc("ceph_test_rados_io options");
- desc.add_options()
- ("help,h",
- "show help message")
- ("listsequence,l",
- "show list of sequences")
- ("dryrun,d",
- "test sequence, do not issue any I/O")
- ("verbose",
- "more verbose output during test")
- ("sequence,s", po::value<int>(),
- "test specified sequence")
- ("seed", po::value<int>(),
- "seed for whole test")
- ("seqseed", po::value<int>(),
- "seed for sequence")
- ("blocksize,b", po::value<Size>(),
- "block size (default 2048)")
- ("chunksize,c", po::value<Size>(),
- "chunk size (default 4096)")
- ("pool,p", po::value<std::string>(),
- "pool name")
- ("object,o", po::value<std::string>()->default_value("test"),
- "object name")
- ("km", po::value<Pair>(),
- "k,m EC pool profile (default 2,2)")
- ("plugin", po::value<PluginString>(),
- "EC plugin (isa or jerasure)")
- ("objectsize", po::value<Pair>(),
- "min,max object size in blocks (default 1,32)")
- ("threads,t", po::value<int>(),
- "number of threads of I/O per object (default 1)")
- ("parallel,p", po::value<int>()->default_value(1),
- "number of objects to exercise in parallel")
- ("testrecovery",
- "Inject errors during sequences to test recovery processes of OSDs")
- ("interactive",
- "interactive mode, execute IO commands from stdin")
- ("allow_pool_autoscaling",
- "Allows pool autoscaling. Disabled by default.")
- ("allow_pool_balancer",
- "Enables pool balancing. Disabled by default.")
- ("allow_pool_deep_scrubbing",
- "Enables pool deep scrub. Disabled by default.")
- ("allow_pool_scrubbing",
- "Enables pool scrubbing. Disabled by default.");
-
- return desc;
- }
-
- int parse_io_seq_options(
- po::variables_map& vm,
- int argc,
- char** argv)
- {
- std::vector<std::string> unrecognized_options;
- try {
- po::options_description desc = get_options_description();
-
- auto parsed = po::command_line_parser(argc, argv)
- .options(desc)
- .allow_unregistered()
- .run();
- po::store(parsed, vm);
- po::notify(vm);
- unrecognized_options = po::collect_unrecognized(parsed.options,
- po::include_positional);
-
- if (!unrecognized_options.empty())
- {
- std::stringstream ss;
- ss << "Unrecognised command options supplied: ";
- while (unrecognized_options.size() > 1)
- {
- ss << unrecognized_options.back().c_str() << ", ";
- unrecognized_options.pop_back();
- }
- ss << unrecognized_options.back();
- dout(0) << ss.str() << dendl;
- return 1;
+ "\t\t done"};
+
+po::options_description get_options_description() {
+ po::options_description desc("ceph_test_rados_io options");
+ desc.add_options()("help,h", "show help message")("listsequence,l",
+ "show list of sequences")(
+ "dryrun,d", "test sequence, do not issue any I/O")(
+ "verbose", "more verbose output during test")(
+ "sequence,s", po::value<int>(), "test specified sequence")(
+ "seed", po::value<int>(), "seed for whole test")(
+ "seqseed", po::value<int>(), "seed for sequence")(
+ "blocksize,b", po::value<Size>(), "block size (default 2048)")(
+ "chunksize,c", po::value<Size>(), "chunk size (default 4096)")(
+ "pool,p", po::value<std::string>(), "pool name")(
+ "object,o", po::value<std::string>()->default_value("test"),
+ "object name")("km", po::value<Pair>(),
+ "k,m EC pool profile (default 2,2)")(
+ "plugin", po::value<PluginString>(), "EC plugin (isa or jerasure)")(
+ "objectsize", po::value<Pair>(),
+ "min,max object size in blocks (default 1,32)")(
+ "threads,t", po::value<int>(),
+ "number of threads of I/O per object (default 1)")(
+ "parallel,p", po::value<int>()->default_value(1),
+ "number of objects to exercise in parallel")(
+ "testrecovery",
+ "Inject errors during sequences to test recovery processes of OSDs")(
+ "interactive", "interactive mode, execute IO commands from stdin")(
+ "allow_pool_autoscaling",
+ "Allows pool autoscaling. Disabled by default.")(
+ "allow_pool_balancer", "Enables pool balancing. Disabled by default.")(
+ "allow_pool_deep_scrubbing",
+ "Enables pool deep scrub. Disabled by default.")(
+ "allow_pool_scrubbing", "Enables pool scrubbing. Disabled by default.");
+
+ return desc;
+}
+
+int parse_io_seq_options(po::variables_map& vm, int argc, char** argv) {
+ std::vector<std::string> unrecognized_options;
+ try {
+ po::options_description desc = get_options_description();
+
+ auto parsed = po::command_line_parser(argc, argv)
+ .options(desc)
+ .allow_unregistered()
+ .run();
+ po::store(parsed, vm);
+ po::notify(vm);
+ unrecognized_options =
+ po::collect_unrecognized(parsed.options, po::include_positional);
+
+ if (!unrecognized_options.empty()) {
+ std::stringstream ss;
+ ss << "Unrecognised command options supplied: ";
+ while (unrecognized_options.size() > 1) {
+ ss << unrecognized_options.back().c_str() << ", ";
+ unrecognized_options.pop_back();
}
- } catch(const po::error& e) {
- std::cerr << "error: " << e.what() << std::endl;
+ ss << unrecognized_options.back();
+ dout(0) << ss.str() << dendl;
return 1;
}
-
- return 0;
+ } catch (const po::error& e) {
+ std::cerr << "error: " << e.what() << std::endl;
+ return 1;
}
+
+ return 0;
}
+} // namespace
template <typename T, int N, const std::array<T, N>& Ts>
-ceph::io_sequence::tester::ProgramOptionSelector<T, N, Ts>
- ::ProgramOptionSelector(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm,
- const std::string& option_name,
- bool set_forced,
- bool select_first)
- : rng(rng),
- option_name(option_name) {
+ceph::io_sequence::tester::ProgramOptionSelector<T, N, Ts>::
+ ProgramOptionSelector(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm, const std::string& option_name,
+ bool set_forced, bool select_first)
+ : rng(rng), option_name(option_name) {
if (set_forced && vm.count(option_name)) {
force_value = vm[option_name].as<T>();
}
}
template <typename T, int N, const std::array<T, N>& Ts>
-bool ceph::io_sequence::tester::ProgramOptionSelector<T, N, Ts>::isForced()
-{
+bool ceph::io_sequence::tester::ProgramOptionSelector<T, N, Ts>::isForced() {
return force_value.has_value();
}
template <typename T, int N, const std::array<T, N>& Ts>
-const T ceph::io_sequence::tester::ProgramOptionSelector<T, N, Ts>::choose()
-{
+const T ceph::io_sequence::tester::ProgramOptionSelector<T, N, Ts>::choose() {
if (force_value.has_value()) {
return *force_value;
} else if (first_value.has_value()) {
return *std::exchange(first_value, std::nullopt);
} else {
- return choices[rng(N-1)];
+ return choices[rng(N - 1)];
}
}
-
-
ceph::io_sequence::tester::SelectObjectSize::SelectObjectSize(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "objectsize", true, true)
-{
-}
-
-
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "objectsize", true, true) {}
ceph::io_sequence::tester::SelectBlockSize::SelectBlockSize(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "blocksize", true, true)
-{
-}
-
-
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "blocksize", true, true) {}
ceph::io_sequence::tester::SelectNumThreads::SelectNumThreads(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "threads", true, true)
-{
-}
-
-
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "threads", true, true) {}
ceph::io_sequence::tester::SelectSeqRange::SelectSeqRange(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "sequence", false, false)
-{
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "sequence", false, false) {
if (vm.count(option_name)) {
ceph::io_exerciser::Sequence s =
- static_cast<ceph::io_exerciser::Sequence>(vm["sequence"].as<int>());
+ static_cast<ceph::io_exerciser::Sequence>(vm["sequence"].as<int>());
if (s < ceph::io_exerciser::Sequence::SEQUENCE_BEGIN ||
s >= ceph::io_exerciser::Sequence::SEQUENCE_END) {
dout(0) << "Sequence argument out of range" << dendl;
throw po::validation_error(po::validation_error::invalid_option_value);
}
ceph::io_exerciser::Sequence e = s;
- force_value = std::make_optional<std::pair<ceph::io_exerciser::Sequence,
- ceph::io_exerciser::Sequence>>(
- std::make_pair(s, ++e));
+ force_value = std::make_optional<
+ std::pair<ceph::io_exerciser::Sequence, ceph::io_exerciser::Sequence>>(
+ std::make_pair(s, ++e));
}
}
-const std::pair<ceph::io_exerciser::Sequence,ceph::io_exerciser::Sequence>
- ceph::io_sequence::tester::SelectSeqRange::choose() {
- if (force_value.has_value())
- {
+const std::pair<ceph::io_exerciser::Sequence, ceph::io_exerciser::Sequence>
+ceph::io_sequence::tester::SelectSeqRange::choose() {
+ if (force_value.has_value()) {
return *force_value;
- }
- else
- {
+ } else {
return std::make_pair(ceph::io_exerciser::Sequence::SEQUENCE_BEGIN,
ceph::io_exerciser::Sequence::SEQUENCE_END);
}
}
-
-
ceph::io_sequence::tester::SelectErasureKM::SelectErasureKM(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "km", true, true)
-{
-}
-
-
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "km", true, true) {}
ceph::io_sequence::tester::SelectErasurePlugin::SelectErasurePlugin(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "plugin", true, false)
-{
-}
-
-
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "plugin", true, false) {}
ceph::io_sequence::tester::SelectErasureChunkSize::SelectErasureChunkSize(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm)
- : ProgramOptionSelector(rng, vm, "chunksize", true, false)
-{
-}
-
-
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm)
+ : ProgramOptionSelector(rng, vm, "chunksize", true, false) {}
ceph::io_sequence::tester::SelectECPool::SelectECPool(
- ceph::util::random_number_generator<int>& rng,
- po::variables_map vm,
- librados::Rados& rados,
- bool dry_run,
- bool allow_pool_autoscaling,
- bool allow_pool_balancer,
- bool allow_pool_deep_scrubbing,
- bool allow_pool_scrubbing)
- : ProgramOptionSelector(rng, vm, "pool", false, false),
- rados(rados),
- dry_run(dry_run),
- allow_pool_autoscaling(allow_pool_autoscaling),
- allow_pool_balancer(allow_pool_balancer),
- allow_pool_deep_scrubbing(allow_pool_deep_scrubbing),
- allow_pool_scrubbing(allow_pool_scrubbing),
- skm(SelectErasureKM(rng, vm)),
- spl(SelectErasurePlugin(rng, vm)),
- scs(SelectErasureChunkSize(rng, vm))
-{
+ ceph::util::random_number_generator<int>& rng, po::variables_map vm,
+ librados::Rados& rados, bool dry_run, bool allow_pool_autoscaling,
+ bool allow_pool_balancer, bool allow_pool_deep_scrubbing,
+ bool allow_pool_scrubbing)
+ : ProgramOptionSelector(rng, vm, "pool", false, false),
+ rados(rados),
+ dry_run(dry_run),
+ allow_pool_autoscaling(allow_pool_autoscaling),
+ allow_pool_balancer(allow_pool_balancer),
+ allow_pool_deep_scrubbing(allow_pool_deep_scrubbing),
+ allow_pool_scrubbing(allow_pool_scrubbing),
+ skm(SelectErasureKM(rng, vm)),
+ spl(SelectErasurePlugin(rng, vm)),
+ scs(SelectErasureChunkSize(rng, vm)) {
if (!skm.isForced()) {
if (vm.count("pool")) {
force_value = vm["pool"].as<std::string>();
}
}
-const std::string ceph::io_sequence::tester::SelectECPool::choose()
-{
- std::pair<int,int> value;
+const std::string ceph::io_sequence::tester::SelectECPool::choose() {
+ std::pair<int, int> value;
if (!skm.isForced() && force_value.has_value()) {
int rc;
bufferlist inbl, outbl;
auto formatter = std::make_shared<JSONFormatter>(false);
- ceph::io_exerciser::json::OSDPoolGetRequest osdPoolGetRequest(*force_value, formatter);
- rc = rados.mon_command(osdPoolGetRequest.encode_json(), inbl, &outbl, nullptr);
+ ceph::io_exerciser::json::OSDPoolGetRequest osdPoolGetRequest(*force_value,
+ formatter);
+ rc = rados.mon_command(osdPoolGetRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
JSONParser p;
ceph::io_exerciser::json::OSDPoolGetReply osdPoolGetReply(formatter);
osdPoolGetReply.decode_json(&p);
- ceph::io_exerciser::json::OSDECProfileGetRequest osdECProfileGetRequest(osdPoolGetReply.erasure_code_profile, formatter);
- rc = rados.mon_command(osdECProfileGetRequest.encode_json(), inbl, &outbl, nullptr);
+ ceph::io_exerciser::json::OSDECProfileGetRequest osdECProfileGetRequest(
+ osdPoolGetReply.erasure_code_profile, formatter);
+ rc = rados.mon_command(osdECProfileGetRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
success = p.parse(outbl.c_str(), outbl.length());
const std::string plugin = std::string(spl.choose());
const uint64_t chunk_size = scs.choose();
- std::string pool_name = "ec_" + plugin +
- "_cs" + std::to_string(chunk_size) +
- "_k" + std::to_string(k) +
- "_m" + std::to_string(m);
- if (!dry_run)
- {
+ std::string pool_name = "ec_" + plugin + "_cs" + std::to_string(chunk_size) +
+ "_k" + std::to_string(k) + "_m" + std::to_string(m);
+ if (!dry_run) {
create_pool(rados, pool_name, plugin, chunk_size, k, m);
}
return pool_name;
}
void ceph::io_sequence::tester::SelectECPool::create_pool(
- librados::Rados& rados,
- const std::string& pool_name,
- const std::string& plugin,
- uint64_t chunk_size,
- int k, int m)
-{
+ librados::Rados& rados, const std::string& pool_name,
+ const std::string& plugin, uint64_t chunk_size, int k, int m) {
int rc;
bufferlist inbl, outbl;
auto formatter = std::make_shared<JSONFormatter>(false);
ceph::io_exerciser::json::OSDECProfileSetRequest ecProfileSetRequest(
- fmt::format("testprofile-{}", pool_name),
- { fmt::format("plugin={}", plugin),
- fmt::format("k={}", k),
- fmt::format("m={}", m),
- fmt::format("stripe_unit={}", chunk_size),
- fmt::format("crush-failure-domain=osd")},
- formatter);
- rc = rados.mon_command(ecProfileSetRequest.encode_json(), inbl, &outbl, nullptr);
+ fmt::format("testprofile-{}", pool_name),
+ {fmt::format("plugin={}", plugin), fmt::format("k={}", k),
+ fmt::format("m={}", m), fmt::format("stripe_unit={}", chunk_size),
+ fmt::format("crush-failure-domain=osd")},
+ formatter);
+ rc = rados.mon_command(ecProfileSetRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
- ceph::io_exerciser::json::OSDECPoolCreateRequest poolCreateRequest(pool_name,
- fmt::format("testprofile-{}", pool_name),
- formatter);
- rc = rados.mon_command(poolCreateRequest.encode_json(), inbl, &outbl, nullptr);
+ ceph::io_exerciser::json::OSDECPoolCreateRequest poolCreateRequest(
+ pool_name, fmt::format("testprofile-{}", pool_name), formatter);
+ rc =
+ rados.mon_command(poolCreateRequest.encode_json(), inbl, &outbl, nullptr);
ceph_assert(rc == 0);
- if (allow_pool_autoscaling)
- {
- ceph::io_exerciser::json::OSDSetRequest setNoAutoscaleRequest("noautoscale",
- std::nullopt,
- formatter);
- rc = rados.mon_command(setNoAutoscaleRequest.encode_json(), inbl, &outbl, nullptr);
+ if (allow_pool_autoscaling) {
+ ceph::io_exerciser::json::OSDSetRequest setNoAutoscaleRequest(
+ "noautoscale", std::nullopt, formatter);
+ rc = rados.mon_command(setNoAutoscaleRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
}
- if (allow_pool_balancer)
- {
+ if (allow_pool_balancer) {
ceph::io_exerciser::json::BalancerOffRequest balancerOffRequest(formatter);
- rc = rados.mon_command(balancerOffRequest.encode_json(), inbl, &outbl, nullptr);
+ rc = rados.mon_command(balancerOffRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
- ceph::io_exerciser::json::BalancerStatusRequest balancerStatusRequest(formatter);
- rc = rados.mon_command(balancerStatusRequest.encode_json(), inbl, &outbl, nullptr);
+ ceph::io_exerciser::json::BalancerStatusRequest balancerStatusRequest(
+ formatter);
+ rc = rados.mon_command(balancerStatusRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
JSONParser p;
ceph_assert(!reply.active);
}
- if (allow_pool_deep_scrubbing)
- {
- ceph::io_exerciser::json::OSDSetRequest setNoDeepScrubRequest("nodeep-scrub",
- std::nullopt,
- formatter);
- rc = rados.mon_command(setNoDeepScrubRequest.encode_json(), inbl, &outbl, nullptr);
+ if (allow_pool_deep_scrubbing) {
+ ceph::io_exerciser::json::OSDSetRequest setNoDeepScrubRequest(
+ "nodeep-scrub", std::nullopt, formatter);
+ rc = rados.mon_command(setNoDeepScrubRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
}
- if (allow_pool_scrubbing)
- {
- ceph::io_exerciser::json::OSDSetRequest setNoScrubRequest("noscrub",
- std::nullopt,
- formatter);
- rc = rados.mon_command(setNoScrubRequest.encode_json(), inbl, &outbl, nullptr);
+ if (allow_pool_scrubbing) {
+ ceph::io_exerciser::json::OSDSetRequest setNoScrubRequest(
+ "noscrub", std::nullopt, formatter);
+ rc = rados.mon_command(setNoScrubRequest.encode_json(), inbl, &outbl,
+ nullptr);
ceph_assert(rc == 0);
}
- ceph::io_exerciser::json
- ::ConfigSetRequest configSetBluestoreDebugRequest("global",
- "bluestore_debug_inject_read_err",
- "true",
- std::nullopt,
- formatter);
- rc = rados.mon_command(configSetBluestoreDebugRequest.encode_json(),
- inbl,
- &outbl,
- nullptr);
+ ceph::io_exerciser::json ::ConfigSetRequest configSetBluestoreDebugRequest(
+ "global", "bluestore_debug_inject_read_err", "true", std::nullopt,
+ formatter);
+ rc = rados.mon_command(configSetBluestoreDebugRequest.encode_json(), inbl,
+ &outbl, nullptr);
ceph_assert(rc == 0);
- ceph::io_exerciser::json
- ::ConfigSetRequest configSetMaxMarkdownRequest("global",
- "osd_max_markdown_count",
- "99999999",
- std::nullopt,
- formatter);
- rc = rados.mon_command(configSetMaxMarkdownRequest.encode_json(),
- inbl,
- &outbl,
- nullptr);
+ ceph::io_exerciser::json ::ConfigSetRequest configSetMaxMarkdownRequest(
+ "global", "osd_max_markdown_count", "99999999", std::nullopt, formatter);
+ rc = rados.mon_command(configSetMaxMarkdownRequest.encode_json(), inbl,
+ &outbl, nullptr);
ceph_assert(rc == 0);
}
-ceph::io_sequence::tester::TestObject::TestObject( const std::string oid,
- librados::Rados& rados,
- boost::asio::io_context& asio,
- SelectBlockSize& sbs,
- SelectECPool& spo,
- 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)
-{
+ceph::io_sequence::tester::TestObject::TestObject(
+ const std::string oid, librados::Rados& rados,
+ boost::asio::io_context& asio, SelectBlockSize& sbs, SelectECPool& spo,
+ 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) {
if (dryrun) {
- exerciser_model = std::make_unique<ceph::io_exerciser::ObjectModel>(oid,
- sbs.choose(),
- rng());
+ exerciser_model = std::make_unique<ceph::io_exerciser::ObjectModel>(
+ oid, sbs.choose(), rng());
} else {
const std::string pool = spo.choose();
poolK = spo.getChosenK();
std::optional<std::vector<int>> cached_shard_order = std::nullopt;
- if (!spo.get_allow_pool_autoscaling() &&
- !spo.get_allow_pool_balancer() &&
+ if (!spo.get_allow_pool_autoscaling() && !spo.get_allow_pool_balancer() &&
!spo.get_allow_pool_deep_scrubbing() &&
- !spo.get_allow_pool_scrubbing())
- {
+ !spo.get_allow_pool_scrubbing()) {
ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, oid, "");
- int rc = rados.mon_command(osdMapRequest.encode_json(), inbl, &outbl, nullptr);
+ int rc =
+ rados.mon_command(osdMapRequest.encode_json(), inbl, &outbl, nullptr);
ceph_assert(rc == 0);
JSONParser p;
cached_shard_order = reply.acting;
}
- exerciser_model = std::make_unique<ceph::io_exerciser::RadosIo>(rados,
- asio,
- pool,
- oid,
- cached_shard_order,
- sbs.choose(),
- rng(),
- threads,
- lock,
- cond);
- dout(0) << "= " << oid << " pool=" << pool
- << " threads=" << threads
- << " blocksize=" << exerciser_model->get_block_size()
- << " =" << dendl;
+ exerciser_model = std::make_unique<ceph::io_exerciser::RadosIo>(
+ rados, asio, pool, oid, cached_shard_order, sbs.choose(), rng(),
+ threads, lock, cond);
+ dout(0) << "= " << oid << " pool=" << pool << " threads=" << threads
+ << " blocksize=" << exerciser_model->get_block_size() << " ="
+ << dendl;
}
obj_size_range = sos.choose();
seq_range = ssr.choose();
curseq = seq_range.first;
- if (testrecovery)
- {
- seq = ceph::io_exerciser::EcIoSequence::generate_sequence(curseq,
- obj_size_range,
- poolK,
- poolM,
- seqseed.value_or(rng()));
- }
- else
- {
- seq = ceph::io_exerciser::IoSequence::generate_sequence(curseq,
- obj_size_range,
- seqseed.value_or(rng()));
+ if (testrecovery) {
+ seq = ceph::io_exerciser::EcIoSequence::generate_sequence(
+ curseq, obj_size_range, poolK, poolM, seqseed.value_or(rng()));
+ } else {
+ seq = ceph::io_exerciser::IoSequence::generate_sequence(
+ curseq, obj_size_range, seqseed.value_or(rng()));
}
op = seq->next();
done = false;
- dout(0) << "== " << exerciser_model->get_oid() << " "
- << curseq << " "
- << seq->get_name_with_seqseed()
- << " ==" <<dendl;
+ dout(0) << "== " << exerciser_model->get_oid() << " " << curseq << " "
+ << seq->get_name_with_seqseed() << " ==" << dendl;
}
-bool ceph::io_sequence::tester::TestObject::readyForIo()
-{
+bool ceph::io_sequence::tester::TestObject::readyForIo() {
return exerciser_model->readyForIoOp(*op);
}
-bool ceph::io_sequence::tester::TestObject::next()
-{
- if (!done)
- {
- if (verbose)
- {
- dout(0) << exerciser_model->get_oid()
- << " Step " << seq->get_step() << ": "
- << op->to_string(exerciser_model->get_block_size()) << dendl;
- }
- else
- {
- dout(5) << exerciser_model->get_oid()
- << " Step " << seq->get_step() << ": "
- << op->to_string(exerciser_model->get_block_size()) << dendl;
+bool ceph::io_sequence::tester::TestObject::next() {
+ if (!done) {
+ if (verbose) {
+ dout(0) << exerciser_model->get_oid() << " Step " << seq->get_step()
+ << ": " << op->to_string(exerciser_model->get_block_size())
+ << dendl;
+ } else {
+ dout(5) << exerciser_model->get_oid() << " Step " << seq->get_step()
+ << ": " << op->to_string(exerciser_model->get_block_size())
+ << dendl;
}
exerciser_model->applyIoOp(*op);
- if (op->getOpType() == ceph::io_exerciser::OpType::Done)
- {
+ if (op->getOpType() == ceph::io_exerciser::OpType::Done) {
curseq = seq->getNextSupportedSequenceId();
- if (curseq >= seq_range.second)
- {
+ if (curseq >= seq_range.second) {
done = true;
dout(0) << exerciser_model->get_oid()
<< " Number of IOs = " << exerciser_model->get_num_io()
<< dendl;
- }
- else
- {
- if (testrecovery)
- {
- seq = ceph::io_exerciser::EcIoSequence::generate_sequence(curseq,
- obj_size_range,
- poolK, poolM,
- seqseed.value_or(rng()));
- }
- else
- {
- seq = ceph::io_exerciser::IoSequence::generate_sequence(curseq,
- obj_size_range,
- seqseed.value_or(rng()));
+ } else {
+ if (testrecovery) {
+ seq = ceph::io_exerciser::EcIoSequence::generate_sequence(
+ curseq, obj_size_range, poolK, poolM, seqseed.value_or(rng()));
+ } else {
+ seq = ceph::io_exerciser::IoSequence::generate_sequence(
+ curseq, obj_size_range, seqseed.value_or(rng()));
}
- dout(0) << "== " << exerciser_model->get_oid() << " "
- << curseq << " " << seq->get_name_with_seqseed()
- << " ==" <<dendl;
+ dout(0) << "== " << exerciser_model->get_oid() << " " << curseq << " "
+ << seq->get_name_with_seqseed() << " ==" << dendl;
op = seq->next();
}
- }
- else
- {
+ } else {
op = seq->next();
}
}
return done;
}
-bool ceph::io_sequence::tester::TestObject::finished()
-{
- return done;
-}
+bool ceph::io_sequence::tester::TestObject::finished() { return done; }
-int ceph::io_sequence::tester::TestObject::get_num_io()
-{
+int ceph::io_sequence::tester::TestObject::get_num_io() {
return exerciser_model->get_num_io();
}
ceph::io_sequence::tester::TestRunner::TestRunner(po::variables_map& vm,
- librados::Rados& rados) :
- rados(rados),
- seed(vm.contains("seed") ? vm["seed"].as<int>() : time(nullptr)),
- rng(ceph::util::random_number_generator<int>(seed)),
- sbs{rng, vm},
- sos{rng, vm},
- spo{rng, vm, rados,
- vm.contains("dryrun"),
- vm.contains("allow_pool_autoscaling"),
- vm.contains("allow_pool_balancer"),
- vm.contains("allow_pool_deep_scrubbing"),
- vm.contains("allow_pool_scrubbing")},
- snt{rng, vm},
- ssr{rng, vm}
-{
+ librados::Rados& rados)
+ : rados(rados),
+ seed(vm.contains("seed") ? vm["seed"].as<int>() : time(nullptr)),
+ rng(ceph::util::random_number_generator<int>(seed)),
+ sbs{rng, vm},
+ sos{rng, vm},
+ spo{rng,
+ vm,
+ rados,
+ vm.contains("dryrun"),
+ vm.contains("allow_pool_autoscaling"),
+ vm.contains("allow_pool_balancer"),
+ vm.contains("allow_pool_deep_scrubbing"),
+ vm.contains("allow_pool_scrubbing")},
+ snt{rng, vm},
+ ssr{rng, vm} {
dout(0) << "Test using seed " << seed << dendl;
verbose = vm.contains("verbose");
allow_pool_deep_scrubbing = vm.contains("allow_pool_deep_scrubbing");
allow_pool_scrubbing = vm.contains("allow_pool_scrubbing");
- if (!dryrun)
- {
+ if (!dryrun) {
guard.emplace(boost::asio::make_work_guard(asio));
- thread = make_named_thread("io_thread",[&asio = asio] { asio.run(); });
+ thread = make_named_thread("io_thread", [&asio = asio] { asio.run(); });
}
show_help = vm.contains("help");
show_sequence = vm.contains("listsequence");
}
-ceph::io_sequence::tester::TestRunner::~TestRunner()
-{
+ceph::io_sequence::tester::TestRunner::~TestRunner() {
if (!dryrun) {
guard = std::nullopt;
asio.stop();
}
}
-void ceph::io_sequence::tester::TestRunner::help()
-{
+void ceph::io_sequence::tester::TestRunner::help() {
std::cout << get_options_description() << std::endl;
- for (auto line : usage)
- {
+ for (auto line : usage) {
std::cout << line << std::endl;
}
}
-void ceph::io_sequence::tester::TestRunner::list_sequence(bool testrecovery)
-{
+void ceph::io_sequence::tester::TestRunner::list_sequence(bool testrecovery) {
// List seqeunces
- std::pair<int,int> obj_size_range = sos.choose();
+ std::pair<int, int> obj_size_range = sos.choose();
ceph::io_exerciser::Sequence s = ceph::io_exerciser::Sequence::SEQUENCE_BEGIN;
std::unique_ptr<ceph::io_exerciser::IoSequence> seq;
- if (testrecovery)
- {
- seq = ceph::io_exerciser::EcIoSequence::generate_sequence(s, obj_size_range,
- spo.getChosenK(),
- spo.getChosenM(),
- seqseed.value_or(rng()));
- }
- else
- {
- seq = ceph::io_exerciser::IoSequence::generate_sequence(s, obj_size_range,
- seqseed.value_or(rng()));
+ if (testrecovery) {
+ seq = ceph::io_exerciser::EcIoSequence::generate_sequence(
+ s, obj_size_range, spo.getChosenK(), spo.getChosenM(),
+ seqseed.value_or(rng()));
+ } else {
+ seq = ceph::io_exerciser::IoSequence::generate_sequence(
+ s, obj_size_range, seqseed.value_or(rng()));
}
- do
- {
+ do {
dout(0) << s << " " << seq->get_name_with_seqseed() << dendl;
s = seq->getNextSupportedSequenceId();
} while (s != ceph::io_exerciser::Sequence::SEQUENCE_END);
}
-void ceph::io_sequence::tester::TestRunner::clear_tokens()
-{
+void ceph::io_sequence::tester::TestRunner::clear_tokens() {
tokens = split.end();
}
-std::string ceph::io_sequence::tester::TestRunner::get_token()
-{
- while (line.empty() || tokens == split.end())
- {
- if (!std::getline(std::cin, line))
- {
+std::string ceph::io_sequence::tester::TestRunner::get_token() {
+ while (line.empty() || tokens == split.end()) {
+ if (!std::getline(std::cin, line)) {
throw std::runtime_error("End of input");
}
split = ceph::split(line);
return std::string(*tokens++);
}
-std::optional<std::string> ceph::io_sequence::tester::TestRunner
- ::get_optional_token()
-{
+std::optional<std::string>
+ceph::io_sequence::tester::TestRunner ::get_optional_token() {
std::optional<std::string> ret = std::nullopt;
- if (tokens != split.end())
- {
+ if (tokens != split.end()) {
ret = std::string(*tokens++);
}
return ret;
}
-uint64_t ceph::io_sequence::tester::TestRunner::get_numeric_token()
-{
+uint64_t ceph::io_sequence::tester::TestRunner::get_numeric_token() {
std::string parse_error;
std::string token = get_token();
uint64_t num = strict_iecstrtoll(token, &parse_error);
- if (!parse_error.empty())
- {
- throw std::runtime_error("Invalid number "+token);
+ if (!parse_error.empty()) {
+ throw std::runtime_error("Invalid number " + token);
}
return num;
}
-std::optional<uint64_t> ceph::io_sequence::tester::TestRunner
- ::get_optional_numeric_token()
-{
+std::optional<uint64_t>
+ceph::io_sequence::tester::TestRunner ::get_optional_numeric_token() {
std::string parse_error;
std::optional<std::string> token = get_optional_token();
- if (token)
- {
+ if (token) {
uint64_t num = strict_iecstrtoll(*token, &parse_error);
- if (!parse_error.empty())
- {
- throw std::runtime_error("Invalid number "+*token);
+ if (!parse_error.empty()) {
+ throw std::runtime_error("Invalid number " + *token);
}
return num;
}
return std::optional<uint64_t>(std::nullopt);
}
-bool ceph::io_sequence::tester::TestRunner::run_test()
-{
- if (show_help)
- {
+bool ceph::io_sequence::tester::TestRunner::run_test() {
+ if (show_help) {
help();
return true;
- }
- else if (show_sequence)
- {
+ } else if (show_sequence) {
list_sequence(testrecovery);
return true;
- }
- else if (interactive)
- {
+ } else if (interactive) {
return run_interactive_test();
- }
- else
- {
+ } else {
return run_automated_test();
}
}
-bool ceph::io_sequence::tester::TestRunner::run_interactive_test()
-{
+bool ceph::io_sequence::tester::TestRunner::run_interactive_test() {
bool done = false;
std::unique_ptr<ceph::io_exerciser::IoOp> ioop;
std::unique_ptr<ceph::io_exerciser::Model> model;
- if (dryrun)
- {
- model = std::make_unique<ceph::io_exerciser::ObjectModel>(object_name,
- sbs.choose(),
- rng());
- }
- else
- {
+ if (dryrun) {
+ model = std::make_unique<ceph::io_exerciser::ObjectModel>(
+ object_name, sbs.choose(), rng());
+ } else {
const std::string pool = spo.choose();
bufferlist inbl, outbl;
- ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, object_name, "");
- int rc = rados.mon_command(osdMapRequest.encode_json(),
- inbl,
- &outbl,
- nullptr);
+ ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, object_name,
+ "");
+ int rc =
+ rados.mon_command(osdMapRequest.encode_json(), inbl, &outbl, nullptr);
ceph_assert(rc == 0);
JSONParser p;
ceph::io_exerciser::json::OSDMapReply reply{};
reply.decode_json(&p);
- model = std::make_unique<ceph::io_exerciser::RadosIo>(rados, asio, pool,
- object_name, reply.acting,
- sbs.choose(), rng(),
- 1, // 1 thread
- lock, cond);
+ model = std::make_unique<ceph::io_exerciser::RadosIo>(
+ rados, asio, pool, object_name, reply.acting, sbs.choose(), rng(),
+ 1, // 1 thread
+ lock, cond);
}
- while (!done)
- {
+ while (!done) {
const std::string op = get_token();
- if (op == "done" || op == "q" || op == "quit")
- {
+ if (op == "done" || op == "q" || op == "quit") {
ioop = ceph::io_exerciser::DoneOp::generate();
- }
- else if (op == "create")
- {
+ } else if (op == "create") {
ioop = ceph::io_exerciser::CreateOp::generate(get_numeric_token());
- }
- else if (op == "remove" || op == "delete")
- {
+ } else if (op == "remove" || op == "delete") {
ioop = ceph::io_exerciser::RemoveOp::generate();
- }
- else if (op == "read")
- {
+ } else if (op == "read") {
uint64_t offset = get_numeric_token();
uint64_t length = get_numeric_token();
ioop = ceph::io_exerciser::SingleReadOp::generate(offset, length);
- }
- else if (op == "read2")
- {
+ } else if (op == "read2") {
uint64_t offset1 = get_numeric_token();
uint64_t length1 = get_numeric_token();
uint64_t offset2 = get_numeric_token();
uint64_t length2 = get_numeric_token();
ioop = DoubleReadOp::generate(offset1, length1, offset2, length2);
- }
- else if (op == "read3")
- {
+ } else if (op == "read3") {
uint64_t offset1 = get_numeric_token();
uint64_t length1 = get_numeric_token();
uint64_t offset2 = get_numeric_token();
uint64_t length2 = get_numeric_token();
uint64_t offset3 = get_numeric_token();
uint64_t length3 = get_numeric_token();
- ioop = TripleReadOp::generate(offset1, length1,
- offset2, length2,
- offset3, length3);
- }
- else if (op == "write")
- {
+ ioop = TripleReadOp::generate(offset1, length1, offset2, length2, offset3,
+ length3);
+ } else if (op == "write") {
uint64_t offset = get_numeric_token();
uint64_t length = get_numeric_token();
ioop = SingleWriteOp::generate(offset, length);
- }
- else if (op == "write2")
- {
+ } else if (op == "write2") {
uint64_t offset1 = get_numeric_token();
uint64_t length1 = get_numeric_token();
uint64_t offset2 = get_numeric_token();
uint64_t length2 = get_numeric_token();
ioop = DoubleWriteOp::generate(offset1, length1, offset2, length2);
- }
- else if (op == "write3")
- {
+ } else if (op == "write3") {
uint64_t offset1 = get_numeric_token();
uint64_t length1 = get_numeric_token();
uint64_t offset2 = get_numeric_token();
uint64_t length2 = get_numeric_token();
uint64_t offset3 = get_numeric_token();
uint64_t length3 = get_numeric_token();
- ioop = TripleWriteOp::generate(offset1, length1,
- offset2, length2,
+ ioop = TripleWriteOp::generate(offset1, length1, offset2, length2,
offset3, length3);
- }
- else if (op == "failedwrite")
- {
+ } else if (op == "failedwrite") {
uint64_t offset = get_numeric_token();
uint64_t length = get_numeric_token();
ioop = SingleFailedWriteOp::generate(offset, length);
- }
- else if (op == "failedwrite2")
- {
+ } else if (op == "failedwrite2") {
uint64_t offset1 = get_numeric_token();
uint64_t length1 = get_numeric_token();
uint64_t offset2 = get_numeric_token();
uint64_t length2 = get_numeric_token();
ioop = DoubleFailedWriteOp::generate(offset1, length1, offset2, length2);
- }
- else if (op == "failedwrite3")
- {
+ } else if (op == "failedwrite3") {
uint64_t offset1 = get_numeric_token();
uint64_t length1 = get_numeric_token();
uint64_t offset2 = get_numeric_token();
uint64_t length2 = get_numeric_token();
uint64_t offset3 = get_numeric_token();
uint64_t length3 = get_numeric_token();
- ioop = TripleFailedWriteOp::generate(offset1, length1,
- offset2, length2,
- offset3, length3);
- }
- else if (op == "injecterror")
- {
+ ioop = TripleFailedWriteOp::generate(offset1, length1, offset2, length2,
+ offset3, length3);
+ } else if (op == "injecterror") {
std::string inject_type = get_token();
int shard = get_numeric_token();
std::optional<int> type = get_optional_numeric_token();
std::optional<int> when = get_optional_numeric_token();
std::optional<int> duration = get_optional_numeric_token();
- if (inject_type == "read")
- {
- ioop = ceph::io_exerciser::InjectReadErrorOp::generate(shard,
- type,
- when,
- duration);
- }
- else if (inject_type == "write")
- {
- ioop = ceph::io_exerciser::InjectWriteErrorOp::generate(shard,
- type,
- when,
- duration);
- }
- else
- {
+ if (inject_type == "read") {
+ ioop = ceph::io_exerciser::InjectReadErrorOp::generate(shard, type,
+ when, duration);
+ } else if (inject_type == "write") {
+ ioop = ceph::io_exerciser::InjectWriteErrorOp::generate(shard, type,
+ when, duration);
+ } else {
clear_tokens();
ioop.reset();
dout(0) << fmt::format("Invalid error inject {}. No action performed.",
- inject_type) << dendl;
+ inject_type)
+ << dendl;
}
- }
- else if (op == "clearinject")
- {
+ } else if (op == "clearinject") {
std::string inject_type = get_token();
int shard = get_numeric_token();
std::optional<int> type = get_optional_numeric_token();
- if (inject_type == "read")
- {
- ioop = ceph::io_exerciser::ClearReadErrorInjectOp::generate(shard,
- type);
- }
- else if (inject_type == "write")
- {
- ioop = ceph::io_exerciser::ClearWriteErrorInjectOp::generate(shard,
- type);
- }
- else
- {
+ if (inject_type == "read") {
+ ioop =
+ ceph::io_exerciser::ClearReadErrorInjectOp::generate(shard, type);
+ } else if (inject_type == "write") {
+ ioop =
+ ceph::io_exerciser::ClearWriteErrorInjectOp::generate(shard, type);
+ } else {
clear_tokens();
ioop.reset();
dout(0) << fmt::format("Invalid error inject {}. No action performed.",
- inject_type) << dendl;
+ inject_type)
+ << dendl;
}
- }
- else
- {
+ } else {
clear_tokens();
ioop.reset();
- dout(0) << fmt::format("Invalid op {}. No action performed.",
- op) << dendl;
+ dout(0) << fmt::format("Invalid op {}. No action performed.", op)
+ << dendl;
}
- if (ioop)
- {
+ if (ioop) {
dout(0) << ioop->to_string(model->get_block_size()) << dendl;
model->applyIoOp(*ioop);
done = ioop->getOpType() == ceph::io_exerciser::OpType::Done;
- if (!done)
- {
+ if (!done) {
ioop = ceph::io_exerciser::BarrierOp::generate();
model->applyIoOp(*ioop);
}
return true;
}
-bool ceph::io_sequence::tester::TestRunner::run_automated_test()
-{
+bool ceph::io_sequence::tester::TestRunner::run_automated_test() {
// Create a test for each object
- std::vector<std::shared_ptr<
- ceph::io_sequence::tester::TestObject>> test_objects;
+ std::vector<std::shared_ptr<ceph::io_sequence::tester::TestObject>>
+ test_objects;
for (int obj = 0; obj < num_objects; obj++) {
std::string name;
name = object_name + std::to_string(obj);
}
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
- )
- );
+ std::make_shared<ceph::io_sequence::tester::TestObject>(
+ name, rados, asio, sbs, spo, sos, snt, ssr, rng, lock, cond, dryrun,
+ verbose, seqseed, testrecovery));
}
- if (!dryrun)
- {
+ if (!dryrun) {
rados.wait_for_latest_osdmap();
}
bool started_io = true;
bool need_wait = true;
- while (started_io || need_wait)
- {
+ while (started_io || need_wait) {
started_io = false;
need_wait = false;
- for (auto obj = test_objects.begin(); obj != test_objects.end(); ++obj)
- {
+ for (auto obj = test_objects.begin(); obj != test_objects.end(); ++obj) {
std::shared_ptr<ceph::io_sequence::tester::TestObject> to = *obj;
- if (!to->finished())
- {
- lock.lock();
- bool ready = to->readyForIo();
- lock.unlock();
- if (ready)
- {
- to->next();
- started_io = true;
- } else {
- need_wait = true;
- }
+ if (!to->finished()) {
+ lock.lock();
+ bool ready = to->readyForIo();
+ lock.unlock();
+ if (ready) {
+ to->next();
+ started_io = true;
+ } else {
+ need_wait = true;
+ }
}
}
- if (!started_io && need_wait)
- {
+ if (!started_io && need_wait) {
std::unique_lock l(lock);
// Recheck with lock incase anything has changed
- for (auto obj = test_objects.begin(); obj != test_objects.end(); ++obj)
- {
+ for (auto obj = test_objects.begin(); obj != test_objects.end(); ++obj) {
std::shared_ptr<ceph::io_sequence::tester::TestObject> to = *obj;
- if (!to->finished())
- {
+ if (!to->finished()) {
need_wait = !to->readyForIo();
- if (!need_wait)
- {
+ if (!need_wait) {
break;
}
}
}
int total_io = 0;
- for (auto obj = test_objects.begin(); obj != test_objects.end(); ++obj)
- {
+ for (auto obj = test_objects.begin(); obj != test_objects.end(); ++obj) {
std::shared_ptr<ceph::io_sequence::tester::TestObject> to = *obj;
total_io += to->get_num_io();
ceph_assert(to->finished());
return true;
}
-int main(int argc, char **argv)
-{
+int main(int argc, char** argv) {
auto args = argv_to_vec(argc, argv);
env_to_vec(args);
auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
- CODE_ENVIRONMENT_UTILITY, 0);
+ CODE_ENVIRONMENT_UTILITY, 0);
common_init_finish(cct.get());
po::variables_map vm;
int rc = parse_io_seq_options(vm, argc, argv);
- if (rc != 0)
- {
+ if (rc != 0) {
return rc;
}
std::unique_ptr<ceph::io_sequence::tester::TestRunner> runner;
try {
runner = std::make_unique<ceph::io_sequence::tester::TestRunner>(vm, rados);
- } catch(const po::error& e) {
+ } catch (const po::error& e) {
return 1;
}
runner->run_test();
+#include <boost/program_options.hpp>
+#include <optional>
#include <utility>
-#include "include/random.h"
-
-#include "global/global_init.h"
-#include "global/global_context.h"
-
#include "common/io_exerciser/IoOp.h"
#include "common/io_exerciser/IoSequence.h"
#include "common/io_exerciser/Model.h"
-
#include "common/split.h"
-
+#include "global/global_context.h"
+#include "global/global_init.h"
+#include "include/random.h"
#include "librados/librados_asio.h"
#include <boost/asio/io_context.hpp>
/* Overview
*
* class ProgramOptionSelector
- * Base class for selector objects below with common code for
+ * Base class for selector objects below with common code for
* selecting options
- *
+ *
* class SelectObjectSize
* Selects min and max object sizes for a test
*
* class SelectErasureKM
* Selects an EC k and m value for a test
- *
+ *
* class SelectErasurePlugin
* Selects an plugin for a test
- *
+ *
* class SelectECPool
* Selects an EC pool (plugin,k and m) for a test. Also creates the
* pool as well.
namespace po = boost::program_options;
-namespace ceph
-{
- namespace io_sequence::tester
- {
- // Choices for min and max object size
- inline constexpr size_t objectSizeSize = 10;
- inline constexpr std::array<std::pair<int,int>,objectSizeSize>
- objectSizeChoices = {{
- {1,32}, // Default - best for boundary checking
- {12,14},
- {28,30},
- {36,38},
- {42,44},
- {52,54},
- {66,68},
- {72,74},
- {83,83},
- {97,97}
- }};
-
- // Choices for block size
- inline constexpr int blockSizeSize = 5;
- inline constexpr std::array<uint64_t, blockSizeSize> blockSizeChoices = {{
- 2048, // Default - test boundaries for EC 4K chunk size
- 512,
- 3767,
- 4096,
- 32768
- }};
-
- // Choices for number of threads
- inline constexpr int threadArraySize = 4;
- inline constexpr std::array<int, threadArraySize> threadCountChoices = {{
- 1, // Default
- 2,
- 4,
- 8
- }};
-
- // Choices for EC k+m profile
- inline constexpr int kmSize = 6;
- inline constexpr std::array<std::pair<int,int>, kmSize> kmChoices = {{
- {2,2}, // Default - reasonable coverage
- {2,1},
- {2,3},
- {3,2},
- {4,2},
- {5,1}
- }};
-
- // Choices for EC chunk size
- inline constexpr int chunkSizeSize = 3;
- inline constexpr std::array<uint64_t, chunkSizeSize> chunkSizeChoices = {{
- 4*1024,
- 64*1024,
- 256*1024
- }};
-
- // Choices for plugin
- inline constexpr int pluginListSize = 2;
- inline constexpr std::array<std::string_view,
- pluginListSize> pluginChoices = {{
- "jerasure",
- "isa"
- }};
-
- inline constexpr std::array<std::pair<ceph::io_exerciser::Sequence,
- ceph::io_exerciser::Sequence>,
- 0> sequencePairs = {{}};
-
- inline constexpr std::array<std::string, 0> poolChoices = {{}};
-
- template <typename T, int N, const std::array<T, N>& Ts>
- class ProgramOptionSelector
- {
- public:
- ProgramOptionSelector(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm,
- const std::string& option_name,
- bool set_forced,
- bool select_first
- );
- virtual ~ProgramOptionSelector() = default;
- bool isForced();
- virtual const T choose();
-
- protected:
- ceph::util::random_number_generator<int>& rng;
- static constexpr std::array<T, N> choices = Ts;
-
- std::optional<T> force_value;
- std::optional<T> first_value;
-
- std::string option_name;
- };
-
- class SelectObjectSize
- : public ProgramOptionSelector<std::pair<int, int>,
- io_sequence::tester::objectSizeSize,
- io_sequence::tester::objectSizeChoices>
- {
- public:
- SelectObjectSize(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm);
- };
-
- class SelectBlockSize
- : public ProgramOptionSelector<uint64_t,
- io_sequence::tester::blockSizeSize,
- io_sequence::tester::blockSizeChoices>
- {
- public:
- SelectBlockSize(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm);
- };
-
- class SelectNumThreads
- : public ProgramOptionSelector<int,
- io_sequence::tester::threadArraySize,
- io_sequence::tester::threadCountChoices>
- {
- public:
- SelectNumThreads(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm);
- };
-
- class SelectSeqRange
- : public ProgramOptionSelector<std::pair<ceph::io_exerciser::Sequence,
- ceph::io_exerciser::Sequence>,
- 0, io_sequence::tester::sequencePairs>
- {
- public:
- SelectSeqRange(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm);
-
- const std::pair<ceph::io_exerciser::Sequence,
- ceph::io_exerciser::Sequence> choose() override;
- };
-
- class SelectErasureKM
- : public ProgramOptionSelector<std::pair<int,int>,
- io_sequence::tester::kmSize,
- io_sequence::tester::kmChoices>
- {
- public:
- SelectErasureKM(ceph::util::random_number_generator<int>& rng,
+namespace ceph {
+namespace io_sequence::tester {
+// Choices for min and max object size
+inline constexpr size_t objectSizeSize = 10;
+inline constexpr std::array<std::pair<int, int>, objectSizeSize>
+ objectSizeChoices = {{{1, 32}, // Default - best for boundary checking
+ {12, 14},
+ {28, 30},
+ {36, 38},
+ {42, 44},
+ {52, 54},
+ {66, 68},
+ {72, 74},
+ {83, 83},
+ {97, 97}}};
+
+// Choices for block size
+inline constexpr int blockSizeSize = 5;
+inline constexpr std::array<uint64_t, blockSizeSize> blockSizeChoices = {
+ {2048, // Default - test boundaries for EC 4K chunk size
+ 512, 3767, 4096, 32768}};
+
+// Choices for number of threads
+inline constexpr int threadArraySize = 4;
+inline constexpr std::array<int, threadArraySize> threadCountChoices = {
+ {1, // Default
+ 2, 4, 8}};
+
+// Choices for EC k+m profile
+inline constexpr int kmSize = 6;
+inline constexpr std::array<std::pair<int, int>, kmSize> kmChoices = {
+ {{2, 2}, // Default - reasonable coverage
+ {2, 1},
+ {2, 3},
+ {3, 2},
+ {4, 2},
+ {5, 1}}};
+
+// Choices for EC chunk size
+inline constexpr int chunkSizeSize = 3;
+inline constexpr std::array<uint64_t, chunkSizeSize> chunkSizeChoices = {
+ {4 * 1024, 64 * 1024, 256 * 1024}};
+
+// Choices for plugin
+inline constexpr int pluginListSize = 2;
+inline constexpr std::array<std::string_view, pluginListSize> pluginChoices = {
+ {"jerasure", "isa"}};
+
+inline constexpr std::array<
+ std::pair<ceph::io_exerciser::Sequence, ceph::io_exerciser::Sequence>, 0>
+ sequencePairs = {{}};
+
+inline constexpr std::array<std::string, 0> poolChoices = {{}};
+
+template <typename T, int N, const std::array<T, N>& Ts>
+class ProgramOptionSelector {
+ public:
+ ProgramOptionSelector(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm, const std::string& option_name,
+ bool set_forced, bool select_first);
+ virtual ~ProgramOptionSelector() = default;
+ bool isForced();
+ virtual const T choose();
+
+ protected:
+ ceph::util::random_number_generator<int>& rng;
+ static constexpr std::array<T, N> choices = Ts;
+
+ std::optional<T> force_value;
+ std::optional<T> first_value;
+
+ std::string option_name;
+};
+
+class SelectObjectSize
+ : public ProgramOptionSelector<std::pair<int, int>,
+ io_sequence::tester::objectSizeSize,
+ io_sequence::tester::objectSizeChoices> {
+ public:
+ SelectObjectSize(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm);
+};
+
+class SelectBlockSize
+ : public ProgramOptionSelector<uint64_t, io_sequence::tester::blockSizeSize,
+ io_sequence::tester::blockSizeChoices> {
+ public:
+ SelectBlockSize(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm);
+};
+
+class SelectNumThreads
+ : public ProgramOptionSelector<int, io_sequence::tester::threadArraySize,
+ io_sequence::tester::threadCountChoices> {
+ public:
+ SelectNumThreads(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm);
+};
+
+class SelectSeqRange
+ : public ProgramOptionSelector<
+ std::pair<ceph::io_exerciser::Sequence, ceph::io_exerciser::Sequence>,
+ 0, io_sequence::tester::sequencePairs> {
+ public:
+ SelectSeqRange(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm);
+
+ const std::pair<ceph::io_exerciser::Sequence, ceph::io_exerciser::Sequence>
+ choose() override;
+};
+
+class SelectErasureKM
+ : public ProgramOptionSelector<std::pair<int, int>,
+ io_sequence::tester::kmSize,
+ io_sequence::tester::kmChoices> {
+ public:
+ SelectErasureKM(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm);
+};
+
+class SelectErasurePlugin
+ : public ProgramOptionSelector<std::string_view,
+ io_sequence::tester::pluginListSize,
+ io_sequence::tester::pluginChoices> {
+ public:
+ SelectErasurePlugin(ceph::util::random_number_generator<int>& rng,
po::variables_map vm);
- };
-
- class SelectErasurePlugin
- : public ProgramOptionSelector<std::string_view,
- io_sequence::tester::pluginListSize,
- io_sequence::tester::pluginChoices>
- {
- public:
- SelectErasurePlugin(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm);
- };
-
- class SelectErasureChunkSize
- : public ProgramOptionSelector<uint64_t,
- io_sequence::tester::chunkSizeSize,
- io_sequence::tester::chunkSizeChoices>
- {
- public:
- SelectErasureChunkSize(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm);
- };
-
- class SelectECPool
- : public ProgramOptionSelector<std::string,
- 0,
- io_sequence::tester::poolChoices>
- {
- public:
- SelectECPool(ceph::util::random_number_generator<int>& rng,
- po::variables_map vm,
- librados::Rados& rados,
- bool dry_run,
- bool allow_pool_autoscaling,
- bool allow_pool_balancer,
- bool allow_pool_deep_scrubbing,
- bool allow_pool_scrubbing);
- const std::string choose() override;
-
- bool get_allow_pool_autoscaling() { return allow_pool_autoscaling; }
- bool get_allow_pool_balancer() { return allow_pool_balancer; }
- bool get_allow_pool_deep_scrubbing() { return allow_pool_deep_scrubbing; }
- bool get_allow_pool_scrubbing() { return allow_pool_scrubbing; }
- int getChosenK() const { return k; }
- int getChosenM() const { return m; }
-
- private:
- void create_pool(librados::Rados& rados,
- const std::string& pool_name,
- const std::string& plugin,
- uint64_t chunk_size,
- int k, int m);
-
- protected:
- librados::Rados& rados;
- bool dry_run;
- bool allow_pool_autoscaling;
- bool allow_pool_balancer;
- bool allow_pool_deep_scrubbing;
- bool allow_pool_scrubbing;
- int k;
- int m;
-
- SelectErasureKM skm;
- SelectErasurePlugin spl;
- SelectErasureChunkSize scs;
- };
-
- class TestObject
- {
- public:
- TestObject( const std::string oid,
- librados::Rados& rados,
- boost::asio::io_context& asio,
- ceph::io_sequence::tester::SelectBlockSize& sbs,
- ceph::io_sequence::tester::SelectECPool& spl,
- ceph::io_sequence::tester::SelectObjectSize& sos,
- ceph::io_sequence::tester::SelectNumThreads& snt,
- ceph::io_sequence::tester::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);
-
- int get_num_io();
- bool readyForIo();
- bool next();
- bool finished();
-
- protected:
- std::unique_ptr<ceph::io_exerciser::Model> exerciser_model;
- std::pair<int,int> obj_size_range;
- std::pair<ceph::io_exerciser::Sequence,
- ceph::io_exerciser::Sequence> seq_range;
- ceph::io_exerciser::Sequence curseq;
- std::unique_ptr<ceph::io_exerciser::IoSequence> seq;
- std::unique_ptr<ceph::io_exerciser::IoOp> op;
- bool done;
- ceph::util::random_number_generator<int>& rng;
- bool verbose;
- std::optional<int> seqseed;
- int poolK;
- int poolM;
- bool testrecovery;
- };
-
- class TestRunner
- {
- public:
- TestRunner(po::variables_map& vm, librados::Rados& rados);
- ~TestRunner();
-
- bool run_test();
-
- private:
- librados::Rados& rados;
- int seed;
- ceph::util::random_number_generator<int> rng;
-
- ceph::io_sequence::tester::SelectBlockSize sbs;
- ceph::io_sequence::tester::SelectObjectSize sos;
- ceph::io_sequence::tester::SelectECPool spo;
- ceph::io_sequence::tester::SelectNumThreads snt;
- ceph::io_sequence::tester::SelectSeqRange ssr;
-
- boost::asio::io_context asio;
- std::thread thread;
- std::optional<boost::asio::executor_work_guard<
- boost::asio::io_context::executor_type>> guard;
- ceph::mutex lock = ceph::make_mutex("RadosIo::lock");
- ceph::condition_variable cond;
-
- bool input_valid;
-
- bool verbose;
- bool dryrun;
- std::optional<int> seqseed;
- bool interactive;
-
- bool testrecovery;
-
- bool allow_pool_autoscaling;
- bool allow_pool_balancer;
- bool allow_pool_deep_scrubbing;
- bool allow_pool_scrubbing;
-
- bool show_sequence;
- bool show_help;
-
- int num_objects;
- std::string object_name;
-
- std::string line;
- ceph::split split = ceph::split("");
- ceph::spliterator tokens;
-
- void clear_tokens();
- std::string get_token();
- std::optional<std::string> get_optional_token();
- uint64_t get_numeric_token();
- std::optional<uint64_t> get_optional_numeric_token();
-
- bool run_automated_test();
-
- bool run_interactive_test();
-
- void help();
- void list_sequence(bool testrecovery);
- };
- }
-}
+};
+
+class SelectErasureChunkSize
+ : public ProgramOptionSelector<uint64_t, io_sequence::tester::chunkSizeSize,
+ io_sequence::tester::chunkSizeChoices> {
+ public:
+ SelectErasureChunkSize(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm);
+};
+
+class SelectECPool
+ : public ProgramOptionSelector<std::string, 0,
+ io_sequence::tester::poolChoices> {
+ public:
+ SelectECPool(ceph::util::random_number_generator<int>& rng,
+ po::variables_map vm, librados::Rados& rados, bool dry_run,
+ bool allow_pool_autoscaling, bool allow_pool_balancer,
+ bool allow_pool_deep_scrubbing, bool allow_pool_scrubbing);
+ const std::string choose() override;
+
+ bool get_allow_pool_autoscaling() { return allow_pool_autoscaling; }
+ bool get_allow_pool_balancer() { return allow_pool_balancer; }
+ bool get_allow_pool_deep_scrubbing() { return allow_pool_deep_scrubbing; }
+ bool get_allow_pool_scrubbing() { return allow_pool_scrubbing; }
+ int getChosenK() const { return k; }
+ int getChosenM() const { return m; }
+
+ private:
+ void create_pool(librados::Rados& rados, const std::string& pool_name,
+ const std::string& plugin, uint64_t chunk_size, int k,
+ int m);
+
+ protected:
+ librados::Rados& rados;
+ bool dry_run;
+ bool allow_pool_autoscaling;
+ bool allow_pool_balancer;
+ bool allow_pool_deep_scrubbing;
+ bool allow_pool_scrubbing;
+ int k;
+ int m;
+
+ SelectErasureKM skm;
+ SelectErasurePlugin spl;
+ SelectErasureChunkSize scs;
+};
+
+class TestObject {
+ public:
+ TestObject(const std::string oid, librados::Rados& rados,
+ boost::asio::io_context& asio,
+ ceph::io_sequence::tester::SelectBlockSize& sbs,
+ ceph::io_sequence::tester::SelectECPool& spl,
+ ceph::io_sequence::tester::SelectObjectSize& sos,
+ ceph::io_sequence::tester::SelectNumThreads& snt,
+ ceph::io_sequence::tester::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);
+
+ int get_num_io();
+ bool readyForIo();
+ bool next();
+ bool finished();
+
+ protected:
+ std::unique_ptr<ceph::io_exerciser::Model> exerciser_model;
+ std::pair<int, int> obj_size_range;
+ std::pair<ceph::io_exerciser::Sequence, ceph::io_exerciser::Sequence>
+ seq_range;
+ ceph::io_exerciser::Sequence curseq;
+ std::unique_ptr<ceph::io_exerciser::IoSequence> seq;
+ std::unique_ptr<ceph::io_exerciser::IoOp> op;
+ bool done;
+ ceph::util::random_number_generator<int>& rng;
+ bool verbose;
+ std::optional<int> seqseed;
+ int poolK;
+ int poolM;
+ bool testrecovery;
+};
+
+class TestRunner {
+ public:
+ TestRunner(po::variables_map& vm, librados::Rados& rados);
+ ~TestRunner();
+
+ bool run_test();
+
+ private:
+ librados::Rados& rados;
+ int seed;
+ ceph::util::random_number_generator<int> rng;
+
+ ceph::io_sequence::tester::SelectBlockSize sbs;
+ ceph::io_sequence::tester::SelectObjectSize sos;
+ ceph::io_sequence::tester::SelectECPool spo;
+ ceph::io_sequence::tester::SelectNumThreads snt;
+ ceph::io_sequence::tester::SelectSeqRange ssr;
+
+ boost::asio::io_context asio;
+ std::thread thread;
+ std::optional<
+ boost::asio::executor_work_guard<boost::asio::io_context::executor_type>>
+ guard;
+ ceph::mutex lock = ceph::make_mutex("RadosIo::lock");
+ ceph::condition_variable cond;
+
+ bool input_valid;
+
+ bool verbose;
+ bool dryrun;
+ std::optional<int> seqseed;
+ bool interactive;
+
+ bool testrecovery;
+
+ bool allow_pool_autoscaling;
+ bool allow_pool_balancer;
+ bool allow_pool_deep_scrubbing;
+ bool allow_pool_scrubbing;
+
+ bool show_sequence;
+ bool show_help;
+
+ int num_objects;
+ std::string object_name;
+
+ std::string line;
+ ceph::split split = ceph::split("");
+ ceph::spliterator tokens;
+
+ void clear_tokens();
+ std::string get_token();
+ std::optional<std::string> get_optional_token();
+ uint64_t get_numeric_token();
+ std::optional<uint64_t> get_optional_numeric_token();
+
+ bool run_automated_test();
+
+ bool run_interactive_test();
+
+ void help();
+ void list_sequence(bool testrecovery);
+};
+} // namespace io_sequence::tester
+} // namespace ceph