From 5811155de658d6198531e5a68c4250337d26a58e Mon Sep 17 00:00:00 2001 From: JonBailey1993 Date: Thu, 14 Nov 2024 16:47:40 +0000 Subject: [PATCH] src/common/io_exerciser: Formatting improvements using clang format Signed-off-by: Jon Bailey --- src/common/io_exerciser/DataGenerator.cc | 794 ++++++-------- src/common/io_exerciser/DataGenerator.h | 268 +++-- src/common/io_exerciser/EcIoSequence.cc | 236 ++--- src/common/io_exerciser/EcIoSequence.h | 112 +- src/common/io_exerciser/IoOp.cc | 461 +++----- src/common/io_exerciser/IoOp.h | 485 ++++----- src/common/io_exerciser/IoSequence.cc | 274 ++--- src/common/io_exerciser/IoSequence.h | 414 ++++---- src/common/io_exerciser/JsonStructures.cc | 419 +++----- src/common/io_exerciser/JsonStructures.h | 589 +++++----- src/common/io_exerciser/Model.cc | 24 +- src/common/io_exerciser/Model.h | 62 +- src/common/io_exerciser/ObjectModel.cc | 297 +++--- src/common/io_exerciser/ObjectModel.h | 75 +- src/common/io_exerciser/OpType.h | 79 +- src/common/io_exerciser/RadosIo.cc | 580 +++++----- src/common/io_exerciser/RadosIo.h | 105 +- src/test/osd/ceph_test_rados_io_sequence.cc | 1061 +++++++------------ src/test/osd/ceph_test_rados_io_sequence.h | 612 +++++------ 19 files changed, 2990 insertions(+), 3957 deletions(-) diff --git a/src/common/io_exerciser/DataGenerator.cc b/src/common/io_exerciser/DataGenerator.cc index 9aa77eeb6e98b..701c32fa9ec21 100644 --- a/src/common/io_exerciser/DataGenerator.cc +++ b/src/common/io_exerciser/DataGenerator.cc @@ -2,32 +2,28 @@ // vim: ts=8 sw=2 smarttab #include "DataGenerator.h" -#include "ObjectModel.h" +#include +#include +#include +#include "ObjectModel.h" #include "common/debug.h" #include "common/dout.h" - #include "fmt/format.h" #include "fmt/ranges.h" -#include -#include -#include - #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::create_generator( - GenerationType generationType, const ObjectModel& model) -{ - switch(generationType) - { + GenerationType generationType, const ObjectModel& model) { + switch (generationType) { case GenerationType::SeededRandom: return std::make_unique(model); case GenerationType::HeaderedSeededRandom: @@ -39,28 +35,25 @@ std::unique_ptr DataGenerator::create_generator( 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]; @@ -70,29 +63,26 @@ ceph::bufferptr SeededRandomGenerator::generate_block(uint64_t block_offset) 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]; @@ -102,141 +92,134 @@ ceph::bufferptr SeededRandomGenerator::generate_wrong_block(uint64_t block_offse 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 unique_run_id) : - SeededRandomGenerator(model), - unique_run_id(unique_run_id.value_or(generate_unique_run_id())) -{ - -} +HeaderedSeededRandomGenerator ::HeaderedSeededRandomGenerator( + const ObjectModel& model, std::optional 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::system_clock::now().time_since_epoch()).count()); + std::mt19937_64(duration_cast( + 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::system_clock::now().time_since_epoch()).count(); + TimeBytes current_time = + duration_cast( + 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 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); } @@ -244,59 +227,51 @@ bool HeaderedSeededRandomGenerator::validate(bufferlist& 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; @@ -304,433 +279,361 @@ void HeaderedSeededRandomGenerator 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 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::max() / 2)); + ceph_assert(m_model.get_block_size() < + (std::numeric_limits::max() / 2)); std::optional 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 seed_found_offsets = m_model.get_seed_offsets(read_seed); if ((seed_found_offsets.size() == 1 && - (static_cast(seed_found_offsets.front() - i) == range_offset)) || - range_length == 0) - { - if (range_length == 0) - { + (static_cast(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(*range_offset) + range_start, - (static_cast(*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(*range_offset) + range_start, + (static_cast(*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 offsets, - const bufferlist& bufferlist) -{ +void HeaderedSeededRandomGenerator ::printDebugInformationForOffsets( + uint64_t read_offset, std::vector 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); } @@ -741,12 +644,9 @@ void HeaderedSeededRandomGenerator } } - 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); } diff --git a/src/common/io_exerciser/DataGenerator.h b/src/common/io_exerciser/DataGenerator.h index 886454fdfa440..bee757863d860 100644 --- a/src/common/io_exerciser/DataGenerator.h +++ b/src/common/io_exerciser/DataGenerator.h @@ -3,8 +3,8 @@ #include #include -#include "include/buffer.h" #include "ObjectModel.h" +#include "include/buffer.h" /* Overview * @@ -23,149 +23,139 @@ * * 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 - 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 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 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 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 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 offsets, + const bufferlist& bufferlist); +}; +} // namespace data_generation +} // namespace io_exerciser +} // namespace ceph diff --git a/src/common/io_exerciser/EcIoSequence.cc b/src/common/io_exerciser/EcIoSequence.cc index cc605de0e00b1..7a8beb7406343 100644 --- a/src/common/io_exerciser/EcIoSequence.cc +++ b/src/common/io_exerciser/EcIoSequence.cc @@ -8,37 +8,30 @@ using IoSequence = ceph::io_exerciser::IoSequence; 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 EcIoSequence::generate_sequence(Sequence sequence, - std::pair obj_size_range, - int k, - int m, - int seed) -{ - switch(sequence) - { +std::unique_ptr EcIoSequence::generate_sequence( + Sequence sequence, std::pair 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(obj_size_range, seed, sequence, k, m); @@ -49,80 +42,69 @@ std::unique_ptr EcIoSequence::generate_sequence(Sequence sequence, } } -EcIoSequence::EcIoSequence(std::pair 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 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(rng(static_cast(InjectOpType::ReadEIO), - static_cast(InjectOpType::ReadMissingShard))); +void EcIoSequence::generate_random_read_inject_type() { + inject_op_type = static_cast( + rng(static_cast(InjectOpType::ReadEIO), + static_cast(InjectOpType::ReadMissingShard))); } -void EcIoSequence::generate_random_write_inject_type() -{ - inject_op_type = static_cast(rng(static_cast(InjectOpType::WriteFailAndRollback), - static_cast(InjectOpType::WriteOSDAbort))); +void EcIoSequence::generate_random_write_inject_type() { + inject_op_type = static_cast( + rng(static_cast(InjectOpType::WriteFailAndRollback), + static_cast(InjectOpType::WriteOSDAbort))); } -ceph::io_exerciser::ReadInjectSequence::ReadInjectSequence(std::pair obj_size_range, - int seed, - Sequence s, - int k, int m) : - EcIoSequence(obj_size_range, seed) -{ +ceph::io_exerciser::ReadInjectSequence::ReadInjectSequence( + std::pair 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 ReadInjectSequence::next() -{ +std::unique_ptr ReadInjectSequence::next() { step++; - if (nextOp) - { + if (nextOp) { std::unique_ptr retOp = nullptr; nextOp.swap(retOp); return retOp; @@ -130,47 +112,48 @@ std::unique_ptr ReadInjectSequence::next() std::unique_ptr 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::max()); + nextOp = InjectReadErrorOp::generate( + *shard_to_inject, 0, 0, std::numeric_limits::max()); break; case InjectOpType::ReadMissingShard: - nextOp = InjectReadErrorOp::generate(*shard_to_inject, 1, 0, std::numeric_limits::max()); + nextOp = InjectReadErrorOp::generate( + *shard_to_inject, 1, 0, std::numeric_limits::max()); break; case InjectOpType::WriteFailAndRollback: - nextOp = InjectWriteErrorOp::generate(*shard_to_inject, 0, 0, std::numeric_limits::max()); + nextOp = InjectWriteErrorOp::generate( + *shard_to_inject, 0, 0, std::numeric_limits::max()); break; case InjectOpType::WriteOSDAbort: - nextOp = InjectWriteErrorOp::generate(*shard_to_inject, 3, 0, std::numeric_limits::max()); + nextOp = InjectWriteErrorOp::generate( + *shard_to_inject, 3, 0, std::numeric_limits::max()); break; case InjectOpType::None: - [[ fallthrough ]]; + [[fallthrough]]; default: ceph_abort_msg("Unsupported operation"); } - break; + break; default: // Do nothing in default case break; @@ -179,85 +162,74 @@ std::unique_ptr ReadInjectSequence::next() return childOp; } -std::unique_ptr 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::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 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 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::Seq10::_next() -{ - if (!inject_error_done) - { +std::unique_ptr ceph::io_exerciser::Seq10::_next() { + if (!inject_error_done) { inject_error_done = true; return InjectWriteErrorOp::generate(*shard_to_inject, 0, 0, std::numeric_limits::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; @@ -266,8 +238,7 @@ std::unique_ptr ceph::io_exerciser::Seq10::_next() successful_write_done = false; if (offset + length >= obj_size) { - if (!test_all_lengths) - { + if (!test_all_lengths) { done = true; return BarrierOp::generate(); } @@ -275,8 +246,7 @@ std::unique_ptr ceph::io_exerciser::Seq10::_next() offset = 0; length++; if (length > obj_size) { - if (!test_all_sizes) - { + if (!test_all_sizes) { done = true; return BarrierOp::generate(); } @@ -287,9 +257,7 @@ std::unique_ptr ceph::io_exerciser::Seq10::_next() } return BarrierOp::generate(); - } - else - { + } else { ceph_abort_msg("Sequence in undefined state. Aborting"); return DoneOp::generate(); } diff --git a/src/common/io_exerciser/EcIoSequence.h b/src/common/io_exerciser/EcIoSequence.h index acfbb34ac27ff..37283b3906bda 100644 --- a/src/common/io_exerciser/EcIoSequence.h +++ b/src/common/io_exerciser/EcIoSequence.h @@ -1,71 +1,65 @@ #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 - generate_sequence(Sequence s, - std::pair 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 generate_sequence( + Sequence s, std::pair obj_size_range, int k, int m, int seed); - protected: - bool setup_inject; - bool clear_inject; - std::optional shard_to_inject; - InjectOpType inject_op_type; + protected: + bool setup_inject; + bool clear_inject; + std::optional shard_to_inject; + InjectOpType inject_op_type; - EcIoSequence(std::pair obj_size_range, int seed); + EcIoSequence(std::pair 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 obj_size_range, int seed, Sequence s, int k, int m); +class ReadInjectSequence : public EcIoSequence { + public: + ReadInjectSequence(std::pair 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 next() override; - std::unique_ptr _next() override; + Sequence get_id() const override; + std::string get_name() const override; + virtual std::unique_ptr next() override; + std::unique_ptr _next() override; - private: - std::unique_ptr child_sequence; - std::unique_ptr nextOp; - }; + private: + std::unique_ptr child_sequence; + std::unique_ptr nextOp; +}; - class Seq10: public EcIoSequence { - public: - Seq10(std::pair obj_size_range, int seed, int k, int m); +class Seq10 : public EcIoSequence { + public: + Seq10(std::pair obj_size_range, int seed, int k, int m); - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _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 diff --git a/src/common/io_exerciser/IoOp.cc b/src/common/io_exerciser/IoOp.cc index 22773a0096080..493d1f435b48a 100644 --- a/src/common/io_exerciser/IoOp.cc +++ b/src/common/io_exerciser/IoOp.cc @@ -1,7 +1,6 @@ #include "IoOp.h" #include "fmt/format.h" - #include "include/ceph_assert.h" using IoOp = ceph::io_exerciser::IoOp; @@ -21,411 +20,297 @@ using SingleFailedWriteOp = ceph::io_exerciser::SingleFailedWriteOp; 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 -ceph::io_exerciser::TestOp::TestOp() : IoOp() -{ +IoOp::IoOp() {} -} - -DoneOp::DoneOp() : TestOp() -{ +template +ceph::io_exerciser::TestOp::TestOp() : IoOp() {} -} +DoneOp::DoneOp() : TestOp() {} -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::generate() -{ +std::unique_ptr DoneOp::generate() { return std::make_unique(); } -BarrierOp::BarrierOp() : TestOp() -{ +BarrierOp::BarrierOp() : TestOp() {} -} - -std::unique_ptr BarrierOp::generate() -{ +std::unique_ptr BarrierOp::generate() { return std::make_unique(); } -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(), - size(size) -{ - -} +CreateOp::CreateOp(uint64_t size) : TestOp(), size(size) {} -std::unique_ptr CreateOp::generate(uint64_t size) -{ +std::unique_ptr CreateOp::generate(uint64_t size) { return std::make_unique(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() -{ - -} +RemoveOp::RemoveOp() : TestOp() {} -std::unique_ptr RemoveOp::generate() -{ +std::unique_ptr RemoveOp::generate() { return std::make_unique(); } -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 -ceph::io_exerciser::ReadWriteOp - ::ReadWriteOp(std::array&& offset, - std::array&& length) : - TestOp(), - 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 +ceph::io_exerciser::ReadWriteOp::ReadWriteOp( + std::array&& offset, + std::array&& length) + : TestOp(), 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 -std::string ceph::io_exerciser::ReadWriteOp - ::to_string(uint64_t block_size) const -{ +template +std::string ceph::io_exerciser::ReadWriteOp::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({offset}, {length}) -{ - -} +SingleReadOp::SingleReadOp(uint64_t offset, uint64_t length) + : ReadWriteOp({offset}, {length}) {} std::unique_ptr SingleReadOp::generate(uint64_t offset, - uint64_t length) -{ + uint64_t length) { return std::make_unique(offset, length); } -DoubleReadOp::DoubleReadOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2) : - ReadWriteOp({offset1, offset2}, {length1, length2}) -{ +DoubleReadOp::DoubleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2) + : ReadWriteOp({offset1, offset2}, {length1, length2}) {} -} - -std::unique_ptr DoubleReadOp::generate(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2) -{ +std::unique_ptr DoubleReadOp::generate(uint64_t offset1, + uint64_t length1, + uint64_t offset2, + uint64_t length2) { return std::make_unique(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({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({offset1, offset2, offset3}, + {length1, length2, length3}) {} -std::unique_ptr TripleReadOp::generate(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2, - uint64_t offset3, uint64_t length3) -{ - return std::make_unique(offset1, length1, - offset2, length2, +std::unique_ptr TripleReadOp::generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2, + uint64_t offset3, uint64_t length3) { + return std::make_unique(offset1, length1, offset2, length2, offset3, length3); } -SingleWriteOp::SingleWriteOp(uint64_t offset, uint64_t length) : - ReadWriteOp({offset}, {length}) -{ +SingleWriteOp::SingleWriteOp(uint64_t offset, uint64_t length) + : ReadWriteOp({offset}, {length}) {} -} - -std::unique_ptr SingleWriteOp::generate(uint64_t offset, uint64_t length) -{ +std::unique_ptr SingleWriteOp::generate(uint64_t offset, + uint64_t length) { return std::make_unique(offset, length); } DoubleWriteOp::DoubleWriteOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2) : - ReadWriteOp({offset1, offset2}, {length1, length2}) -{ + uint64_t offset2, uint64_t length2) + : ReadWriteOp({offset1, offset2}, {length1, length2}) {} -} - -std::unique_ptr DoubleWriteOp::generate(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2) -{ +std::unique_ptr DoubleWriteOp::generate(uint64_t offset1, + uint64_t length1, + uint64_t offset2, + uint64_t length2) { return std::make_unique(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({offset1, offset2, offset3}, {length1, length2, length3}) -{ - -} - -std::unique_ptr TripleWriteOp::generate(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2, - uint64_t offset3, uint64_t length3) -{ - return std::make_unique(offset1, length1, - offset2, length2, + uint64_t offset3, uint64_t length3) + : ReadWriteOp({offset1, offset2, offset3}, + {length1, length2, length3}) {} + +std::unique_ptr TripleWriteOp::generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2, + uint64_t offset3, uint64_t length3) { + return std::make_unique(offset1, length1, offset2, length2, offset3, length3); } -SingleFailedWriteOp::SingleFailedWriteOp(uint64_t offset, uint64_t length) : - ReadWriteOp({offset}, {length}) -{ +SingleFailedWriteOp::SingleFailedWriteOp(uint64_t offset, uint64_t length) + : ReadWriteOp({offset}, {length}) {} -} - -std::unique_ptr SingleFailedWriteOp::generate(uint64_t offset, - uint64_t length) -{ +std::unique_ptr SingleFailedWriteOp::generate( + uint64_t offset, uint64_t length) { return std::make_unique(offset, length); } DoubleFailedWriteOp::DoubleFailedWriteOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2) : - ReadWriteOp({offset1, offset2}, {length1, length2}) -{ - -} + uint64_t offset2, uint64_t length2) + : ReadWriteOp({offset1, offset2}, + {length1, length2}) {} -std::unique_ptr DoubleFailedWriteOp::generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2) -{ - return std::make_unique(offset1, length1, offset2, length2); +std::unique_ptr DoubleFailedWriteOp::generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2) { + return std::make_unique(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({offset1, offset2, offset3}, - {length1, length2, length3}) -{ - -} + uint64_t offset3, uint64_t length3) + : ReadWriteOp({offset1, offset2, offset3}, + {length1, length2, length3}) {} -std::unique_ptr TripleFailedWriteOp::generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2, - uint64_t offset3, - uint64_t length3) -{ - return std::make_unique(offset1, length1, - offset2, length2, - offset3, length3); +std::unique_ptr TripleFailedWriteOp::generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2, + uint64_t offset3, uint64_t length3) { + return std::make_unique(offset1, length1, offset2, + length2, offset3, length3); } template -ceph::io_exerciser::InjectErrorOp - ::InjectErrorOp(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration) : - TestOp(), - shard(shard), - type(type), - when(when), - duration(duration) -{ - -} +ceph::io_exerciser::InjectErrorOp::InjectErrorOp( + int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration) + : TestOp(), + shard(shard), + type(type), + when(when), + duration(duration) {} template -std::string ceph::io_exerciser::InjectErrorOp::to_string(uint64_t blocksize) const -{ +std::string ceph::io_exerciser::InjectErrorOp::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& type, - const std::optional& when, - const std::optional& duration) : - InjectErrorOp(shard, type, when, duration) -{ - -} - -std::unique_ptr ceph::io_exerciser - ::InjectReadErrorOp::generate(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& 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& type, + const std::optional& when, + const std::optional& duration) + : InjectErrorOp(shard, type, when, duration) {} + +std::unique_ptr +ceph::io_exerciser ::InjectReadErrorOp::generate( + int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration) { return std::make_unique(shard, type, when, duration); } -ceph::io_exerciser::InjectWriteErrorOp::InjectWriteErrorOp(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration) : - InjectErrorOp(shard, type, when, duration) -{ +ceph::io_exerciser::InjectWriteErrorOp::InjectWriteErrorOp( + int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration) + : InjectErrorOp(shard, type, when, duration) {} -} - -std::unique_ptr ceph::io_exerciser - ::InjectWriteErrorOp::generate(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration) -{ +std::unique_ptr +ceph::io_exerciser ::InjectWriteErrorOp::generate( + int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration) { return std::make_unique(shard, type, when, duration); } - - template -ceph::io_exerciser::ClearErrorInjectOp - ::ClearErrorInjectOp(int shard, const std::optional& type) : - TestOp(), - shard(shard), - type(type) -{ - -} +ceph::io_exerciser::ClearErrorInjectOp::ClearErrorInjectOp( + int shard, const std::optional& type) + : TestOp(), shard(shard), type(type) {} template -std::string ceph::io_exerciser::ClearErrorInjectOp::to_string(uint64_t blocksize) const -{ +std::string ceph::io_exerciser::ClearErrorInjectOp::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& type) : - ClearErrorInjectOp(shard, type) -{ - -} +ceph::io_exerciser::ClearReadErrorInjectOp::ClearReadErrorInjectOp( + int shard, const std::optional& type) + : ClearErrorInjectOp(shard, type) {} -std::unique_ptr ceph::io_exerciser - ::ClearReadErrorInjectOp::generate(int shard, const std::optional& type) -{ +std::unique_ptr +ceph::io_exerciser ::ClearReadErrorInjectOp::generate( + int shard, const std::optional& type) { return std::make_unique(shard, type); } -ceph::io_exerciser::ClearWriteErrorInjectOp::ClearWriteErrorInjectOp(int shard, - const std::optional& type) : - ClearErrorInjectOp(shard, type) -{ - -} +ceph::io_exerciser::ClearWriteErrorInjectOp::ClearWriteErrorInjectOp( + int shard, const std::optional& type) + : ClearErrorInjectOp(shard, type) {} -std::unique_ptr ceph::io_exerciser - ::ClearWriteErrorInjectOp::generate(int shard, const std::optional& type) -{ +std::unique_ptr +ceph::io_exerciser ::ClearWriteErrorInjectOp::generate( + int shard, const std::optional& type) { return std::make_unique(shard, type); } \ No newline at end of file diff --git a/src/common/io_exerciser/IoOp.h b/src/common/io_exerciser/IoOp.h index 45b4ab6467806..1887eafcc1f41 100644 --- a/src/common/io_exerciser/IoOp.h +++ b/src/common/io_exerciser/IoOp.h @@ -1,9 +1,9 @@ #pragma once #include +#include #include #include -#include #include "OpType.h" @@ -15,265 +15,234 @@ */ 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 - class TestOp : public IoOp - { - public: - TestOp(); - constexpr OpType getOpType() const override { return opType; } - }; - - class DoneOp : public TestOp - { - public: - DoneOp(); - static std::unique_ptr generate(); - std::string to_string(uint64_t block_size) const override; - }; - - class BarrierOp : public TestOp - { - public: - BarrierOp(); - static std::unique_ptr generate(); - std::string to_string(uint64_t block_size) const override; - }; - - class CreateOp : public TestOp - { - public: - CreateOp(uint64_t size); - static std::unique_ptr generate(uint64_t size); - std::string to_string(uint64_t block_size) const override; - uint64_t size; - }; - - class RemoveOp : public TestOp - { - public: - RemoveOp(); - static std::unique_ptr generate(); - std::string to_string(uint64_t block_size) const override; - }; - - template - class ReadWriteOp : public TestOp - { - public: - std::array offset; - std::array length; - - protected: - ReadWriteOp(std::array&& offset, - std::array&& length); - std::string to_string(uint64_t block_size) const override; - }; - - class SingleReadOp : public ReadWriteOp - { - public: - SingleReadOp(uint64_t offset, uint64_t length); - static std::unique_ptr generate(uint64_t offset, - uint64_t length); - }; - - class DoubleReadOp : public ReadWriteOp - { - public: - DoubleReadOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2); - static std::unique_ptr generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2); - }; - - class TripleReadOp : public ReadWriteOp - { - public: - TripleReadOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2, - uint64_t offset3, uint64_t length3); - static std::unique_ptr generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2, - uint64_t offset3, - uint64_t length3); - }; - - class SingleWriteOp : public ReadWriteOp - { - public: - SingleWriteOp(uint64_t offset, uint64_t length); - static std::unique_ptr 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 +class TestOp : public IoOp { + public: + TestOp(); + constexpr OpType getOpType() const override { return opType; } +}; + +class DoneOp : public TestOp { + public: + DoneOp(); + static std::unique_ptr generate(); + std::string to_string(uint64_t block_size) const override; +}; + +class BarrierOp : public TestOp { + public: + BarrierOp(); + static std::unique_ptr generate(); + std::string to_string(uint64_t block_size) const override; +}; + +class CreateOp : public TestOp { + public: + CreateOp(uint64_t size); + static std::unique_ptr generate(uint64_t size); + std::string to_string(uint64_t block_size) const override; + uint64_t size; +}; + +class RemoveOp : public TestOp { + public: + RemoveOp(); + static std::unique_ptr generate(); + std::string to_string(uint64_t block_size) const override; +}; + +template +class ReadWriteOp : public TestOp { + public: + std::array offset; + std::array length; + + protected: + ReadWriteOp(std::array&& offset, + std::array&& length); + std::string to_string(uint64_t block_size) const override; +}; + +class SingleReadOp : public ReadWriteOp { + public: + SingleReadOp(uint64_t offset, uint64_t length); + static std::unique_ptr generate(uint64_t offset, + uint64_t length); +}; + +class DoubleReadOp : public ReadWriteOp { + public: + DoubleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2); + static std::unique_ptr generate(uint64_t offset1, + uint64_t length1, + uint64_t offset2, + uint64_t length2); +}; + +class TripleReadOp : public ReadWriteOp { + public: + TripleReadOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2, uint64_t offset3, uint64_t length3); + static std::unique_ptr generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2, + uint64_t offset3, uint64_t length3); +}; + +class SingleWriteOp : public ReadWriteOp { + public: + SingleWriteOp(uint64_t offset, uint64_t length); + static std::unique_ptr generate(uint64_t offset, + uint64_t length); +}; + +class DoubleWriteOp : public ReadWriteOp { + public: + DoubleWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2); + static std::unique_ptr generate(uint64_t offset1, + uint64_t length1, + uint64_t offset2, + uint64_t length2); +}; + +class TripleWriteOp : public ReadWriteOp { + public: + TripleWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2, uint64_t offset3, uint64_t length3); + static std::unique_ptr generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2, + uint64_t offset3, uint64_t length3); +}; + +class SingleFailedWriteOp : public ReadWriteOp { + public: + SingleFailedWriteOp(uint64_t offset, uint64_t length); + static std::unique_ptr generate(uint64_t offset, uint64_t length); - }; - - class DoubleWriteOp : public ReadWriteOp - { - public: - DoubleWriteOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2); - static std::unique_ptr generate(uint64_t offset1, +}; + +class DoubleFailedWriteOp : public ReadWriteOp { + public: + DoubleFailedWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2); + static std::unique_ptr generate(uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2); - }; - - class TripleWriteOp : public ReadWriteOp - { - public: - TripleWriteOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2, - uint64_t offset3, uint64_t length3); - static std::unique_ptr generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2, - uint64_t offset3, - uint64_t length3); - }; - - class SingleFailedWriteOp : public ReadWriteOp - { - public: - SingleFailedWriteOp(uint64_t offset, uint64_t length); - static std::unique_ptr generate(uint64_t offset, - uint64_t length); - }; - - class DoubleFailedWriteOp : public ReadWriteOp - { - public: - DoubleFailedWriteOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2); - static std::unique_ptr generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2); - }; - - class TripleFailedWriteOp : public ReadWriteOp - { - public: - TripleFailedWriteOp(uint64_t offset1, uint64_t length1, - uint64_t offset2, uint64_t length2, - uint64_t offset3, uint64_t length3); - static std::unique_ptr generate(uint64_t offset1, - uint64_t length1, - uint64_t offset2, - uint64_t length2, - uint64_t offset3, - uint64_t length3); - }; - - template - class InjectErrorOp : public TestOp - { - public: - InjectErrorOp(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration); - - std::string to_string(uint64_t block_size) const override; - - int shard; - std::optional type; - std::optional when; - std::optional duration; - - protected: - virtual inline constexpr std::string_view get_inject_type_string() const = 0; - }; - - class InjectReadErrorOp : public InjectErrorOp - { - public: - InjectReadErrorOp(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration); - - static std::unique_ptr generate(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration); - - protected: - inline constexpr std::string_view get_inject_type_string() const override - { return "read"; } - }; - - class InjectWriteErrorOp : public InjectErrorOp - { - public: - InjectWriteErrorOp(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration); - - static std::unique_ptr generate(int shard, - const std::optional& type, - const std::optional& when, - const std::optional& duration); - - protected: - inline constexpr std::string_view get_inject_type_string() const override - { return "write"; } - }; - - template - class ClearErrorInjectOp : public TestOp - { - public: - ClearErrorInjectOp(int shard, const std::optional& type); - - std::string to_string(uint64_t block_size) const override; - - int shard; - std::optional type; - - protected: - virtual inline constexpr std::string_view get_inject_type_string() const = 0; - }; - - class ClearReadErrorInjectOp : public ClearErrorInjectOp - { - public: - ClearReadErrorInjectOp(int shard, const std::optional& type); - - static std::unique_ptr generate(int shard, - const std::optional& type); - - protected: - inline constexpr std::string_view get_inject_type_string() const override - { return "read"; } - }; - - class ClearWriteErrorInjectOp : public ClearErrorInjectOp - { - public: - ClearWriteErrorInjectOp(int shard, const std::optional& type); - - static std::unique_ptr generate(int shard, - const std::optional& type); - - protected: - inline constexpr std::string_view get_inject_type_string() const override - { return "write"; } - }; +}; + +class TripleFailedWriteOp : public ReadWriteOp { + public: + TripleFailedWriteOp(uint64_t offset1, uint64_t length1, uint64_t offset2, + uint64_t length2, uint64_t offset3, uint64_t length3); + static std::unique_ptr generate( + uint64_t offset1, uint64_t length1, uint64_t offset2, uint64_t length2, + uint64_t offset3, uint64_t length3); +}; + +template +class InjectErrorOp : public TestOp { + public: + InjectErrorOp(int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration); + + std::string to_string(uint64_t block_size) const override; + + int shard; + std::optional type; + std::optional when; + std::optional duration; + + protected: + virtual inline constexpr std::string_view get_inject_type_string() const = 0; +}; + +class InjectReadErrorOp : public InjectErrorOp { + public: + InjectReadErrorOp(int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration); + + static std::unique_ptr generate( + int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration); + + protected: + inline constexpr std::string_view get_inject_type_string() const override { + return "read"; + } +}; + +class InjectWriteErrorOp : public InjectErrorOp { + public: + InjectWriteErrorOp(int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration); + + static std::unique_ptr generate( + int shard, const std::optional& type, + const std::optional& when, + const std::optional& duration); + + protected: + inline constexpr std::string_view get_inject_type_string() const override { + return "write"; + } +}; + +template +class ClearErrorInjectOp : public TestOp { + public: + ClearErrorInjectOp(int shard, const std::optional& type); + + std::string to_string(uint64_t block_size) const override; + + int shard; + std::optional type; + + protected: + virtual inline constexpr std::string_view get_inject_type_string() const = 0; +}; + +class ClearReadErrorInjectOp + : public ClearErrorInjectOp { + public: + ClearReadErrorInjectOp(int shard, const std::optional& type); + + static std::unique_ptr generate( + int shard, const std::optional& type); + + protected: + inline constexpr std::string_view get_inject_type_string() const override { + return "read"; + } +}; + +class ClearWriteErrorInjectOp + : public ClearErrorInjectOp { + public: + ClearWriteErrorInjectOp(int shard, const std::optional& type); + + static std::unique_ptr generate( + int shard, const std::optional& 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 diff --git a/src/common/io_exerciser/IoSequence.cc b/src/common/io_exerciser/IoSequence.cc index f14f0d117da8d..83f1cc595a534 100644 --- a/src/common/io_exerciser/IoSequence.cc +++ b/src/common/io_exerciser/IoSequence.cc @@ -4,10 +4,9 @@ using IoOp = ceph::io_exerciser::IoOp; 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; @@ -48,15 +47,12 @@ std::ostream& ceph::io_exerciser::operator<<(std::ostream& os, const Sequence& s 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::generate_sequence(Sequence s, - std::pair obj_size_range, - int seed) -{ +std::unique_ptr IoSequence::generate_sequence( + Sequence s, std::pair obj_size_range, int seed) { switch (s) { case Sequence::SEQUENCE_SEQ0: return std::make_unique(obj_size_range, seed); @@ -79,8 +75,9 @@ std::unique_ptr IoSequence::generate_sequence(Sequence s, case Sequence::SEQUENCE_SEQ9: return std::make_unique(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; @@ -88,32 +85,28 @@ std::unique_ptr IoSequence::generate_sequence(Sequence s, return nullptr; } -IoSequence::IoSequence(std::pair 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 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; @@ -123,23 +116,20 @@ void IoSequence::set_min_object_size(uint64_t 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 IoSequence::increment_object_size() -{ +std::unique_ptr IoSequence::increment_object_size() { obj_size++; if (obj_size > max_obj_size) { done = true; @@ -150,15 +140,11 @@ std::unique_ptr IoSequence::increment_object_size() 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; } } @@ -166,8 +152,7 @@ Sequence IoSequence::getNextSupportedSequenceId() const return Sequence::SEQUENCE_END; } -std::unique_ptr IoSequence::next() -{ +std::unique_ptr IoSequence::next() { step++; if (remove) { remove = false; @@ -188,28 +173,22 @@ std::unique_ptr IoSequence::next() return _next(); } - - -ceph::io_exerciser::Seq0::Seq0(std::pair obj_size_range, int seed) : - IoSequence(obj_size_range, seed), offset(0) -{ +ceph::io_exerciser::Seq0::Seq0(std::pair 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::Seq0::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq0::_next() { std::unique_ptr r; if (offset >= obj_size) { done = true; @@ -226,27 +205,21 @@ std::unique_ptr ceph::io_exerciser::Seq0::_next() return r; } - - -ceph::io_exerciser::Seq1::Seq1(std::pair obj_size_range, int seed) : - IoSequence(obj_size_range, seed) -{ +ceph::io_exerciser::Seq1::Seq1(std::pair 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::Seq1::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq1::_next() { barrier = true; if (count-- == 0) { done = true; @@ -257,36 +230,25 @@ std::unique_ptr ceph::io_exerciser::Seq1::_next() 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 obj_size_range, int seed) + : IoSequence(obj_size_range, seed), offset(0), length(0) {} - -ceph::io_exerciser::Seq2::Seq2(std::pair 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::Seq2::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq2::_next() { length++; if (length > obj_size - offset) { length = 1; @@ -300,26 +262,20 @@ std::unique_ptr ceph::io_exerciser::Seq2::_next() return SingleReadOp::generate(offset, length); } - - -ceph::io_exerciser::Seq3::Seq3(std::pair obj_size_range, int seed) : - IoSequence(obj_size_range, seed), offset1(0), offset2(0) -{ +ceph::io_exerciser::Seq3::Seq3(std::pair 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::Seq3::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq3::_next() { offset2++; if (offset2 >= obj_size - offset1) { offset2 = 1; @@ -333,26 +289,20 @@ std::unique_ptr ceph::io_exerciser::Seq3::_next() return DoubleReadOp::generate(offset1, 1, offset1 + offset2, 1); } - - -ceph::io_exerciser::Seq4::Seq4(std::pair obj_size_range, int seed) : - IoSequence(obj_size_range, seed), offset1(0), offset2(1) -{ +ceph::io_exerciser::Seq4::Seq4(std::pair 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::Seq4::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq4::_next() { offset2++; if (offset2 >= obj_size - offset1) { offset2 = 2; @@ -363,30 +313,26 @@ std::unique_ptr ceph::io_exerciser::Seq4::_next() 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 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 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::Seq5::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq5::_next() { if (offset >= obj_size) { if (!doneread) { if (!donebarrier) { @@ -412,27 +358,22 @@ std::unique_ptr ceph::io_exerciser::Seq5::_next() return r; } +ceph::io_exerciser::Seq6::Seq6(std::pair 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 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::Seq6::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq6::_next() { if (offset >= obj_size) { if (!doneread) { if (!donebarrier) { @@ -461,27 +402,21 @@ std::unique_ptr ceph::io_exerciser::Seq6::_next() return r; } - - -ceph::io_exerciser::Seq7::Seq7(std::pair obj_size_range, int seed) : - IoSequence(obj_size_range, seed) -{ +ceph::io_exerciser::Seq7::Seq7(std::pair 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::Seq7::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq7::_next() { if (!doneread) { if (!donebarrier) { donebarrier = true; @@ -494,38 +429,32 @@ std::unique_ptr ceph::io_exerciser::Seq7::_next() 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 obj_size_range, int seed) : - IoSequence(obj_size_range, seed), offset1(0), offset2(1) -{ +ceph::io_exerciser::Seq8::Seq8(std::pair 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::Seq8::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq8::_next() { if (!doneread) { if (!donebarrier) { donebarrier = true; @@ -547,29 +476,22 @@ std::unique_ptr ceph::io_exerciser::Seq8::_next() } 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 obj_size_range, int seed) + : IoSequence(obj_size_range, seed), offset(0), length(0) {} - -ceph::io_exerciser::Seq9::Seq9(std::pair 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::Seq9::_next() -{ +std::unique_ptr ceph::io_exerciser::Seq9::_next() { if (!doneread) { if (!donebarrier) { donebarrier = true; diff --git a/src/common/io_exerciser/IoSequence.h b/src/common/io_exerciser/IoSequence.h index 46116c5a1c6ed..b6c254cf096e0 100644 --- a/src/common/io_exerciser/IoSequence.h +++ b/src/common/io_exerciser/IoSequence.h @@ -3,7 +3,6 @@ #pragma once #include "IoOp.h" - #include "include/random.h" /* Overview @@ -29,210 +28,209 @@ */ 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 next(); - - virtual bool is_supported(Sequence sequence) const; - static std::unique_ptr - generate_sequence(Sequence s, - std::pair 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 rng = - ceph::util::random_number_generator(); - - IoSequence(std::pair obj_size_range, int seed); - - virtual std::unique_ptr _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 increment_object_size(); - }; - - class Seq0: public IoSequence { - public: - Seq0(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - uint64_t offset; - uint64_t length; - }; - - class Seq1: public IoSequence { - public: - Seq1(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - int count; - }; - - class Seq2: public IoSequence { - public: - Seq2(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - uint64_t offset; - uint64_t length; - }; - - class Seq3: public IoSequence { - public: - Seq3(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - private: - uint64_t offset1; - uint64_t offset2; - }; - - class Seq4: public IoSequence { - public: - Seq4(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - uint64_t offset1; - uint64_t offset2; - }; - - class Seq5: public IoSequence { - public: - Seq5(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - uint64_t offset; - uint64_t length; - bool doneread; - bool donebarrier; - }; - - class Seq6: public IoSequence { - public: - Seq6(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - uint64_t offset; - uint64_t length; - bool doneread; - bool donebarrier; - }; - - class Seq7: public IoSequence { - public: - Seq7(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _next() override; - - private: - uint64_t offset; - bool doneread = true; - bool donebarrier = false; - }; - - class Seq8: public IoSequence { - public: - Seq8(std::pair obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _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 obj_size_range, int seed); - - Sequence get_id() const override; - std::string get_name() const override; - std::unique_ptr _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 next(); + + virtual bool is_supported(Sequence sequence) const; + static std::unique_ptr generate_sequence( + Sequence s, std::pair 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 rng = + ceph::util::random_number_generator(); + + IoSequence(std::pair obj_size_range, int seed); + + virtual std::unique_ptr _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 increment_object_size(); +}; + +class Seq0 : public IoSequence { + public: + Seq0(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset; + uint64_t length; +}; + +class Seq1 : public IoSequence { + public: + Seq1(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + int count; +}; + +class Seq2 : public IoSequence { + public: + Seq2(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset; + uint64_t length; +}; + +class Seq3 : public IoSequence { + public: + Seq3(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset1; + uint64_t offset2; +}; + +class Seq4 : public IoSequence { + public: + Seq4(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset1; + uint64_t offset2; +}; + +class Seq5 : public IoSequence { + public: + Seq5(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset; + uint64_t length; + bool doneread; + bool donebarrier; +}; + +class Seq6 : public IoSequence { + public: + Seq6(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset; + uint64_t length; + bool doneread; + bool donebarrier; +}; + +class Seq7 : public IoSequence { + public: + Seq7(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; + + private: + uint64_t offset; + bool doneread = true; + bool donebarrier = false; +}; + +class Seq8 : public IoSequence { + public: + Seq8(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _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 obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; +}; +} // namespace io_exerciser +} // namespace ceph \ No newline at end of file diff --git a/src/common/io_exerciser/JsonStructures.cc b/src/common/io_exerciser/JsonStructures.cc index ba41c226264f4..c330484e9370a 100644 --- a/src/common/io_exerciser/JsonStructures.cc +++ b/src/common/io_exerciser/JsonStructures.cc @@ -1,18 +1,14 @@ #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 formatter) : - formatter(formatter) -{ - -} +JSONStructure::JSONStructure(std::shared_ptr formatter) + : formatter(formatter) {} -std::string JSONStructure::encode_json() -{ +std::string JSONStructure::encode_json() { oss.clear(); dump(); @@ -23,23 +19,16 @@ std::string JSONStructure::encode_json() OSDMapRequest::OSDMapRequest(const std::string& pool_name, const std::string& object, const std::string& nspace, - std::shared_ptr formatter) : - JSONStructure(formatter), - pool(pool_name), - object(object), - nspace(nspace) -{ - -} - -OSDMapRequest::OSDMapRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ + std::shared_ptr formatter) + : JSONStructure(formatter), + pool(pool_name), + object(object), + nspace(nspace) {} -} +OSDMapRequest::OSDMapRequest(std::shared_ptr 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); @@ -47,8 +36,7 @@ void OSDMapRequest::decode_json(JSONObj* 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()); @@ -58,14 +46,10 @@ void OSDMapRequest::dump() const formatter->close_section(); } -OSDMapReply::OSDMapReply(std::shared_ptr formatter) : - JSONStructure(formatter) -{ - -} +OSDMapReply::OSDMapReply(std::shared_ptr 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); @@ -78,8 +62,7 @@ void OSDMapReply::decode_json(JSONObj* 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()); @@ -94,20 +77,13 @@ void OSDMapReply::dump() const formatter->close_section(); } -ceph::io_exerciser::json::OSDPoolGetRequest - ::OSDPoolGetRequest(const std::string& pool_name, - std::shared_ptr formatter) : - JSONStructure(formatter), - pool(pool_name) -{ +ceph::io_exerciser::json::OSDPoolGetRequest ::OSDPoolGetRequest( + const std::string& pool_name, std::shared_ptr formatter) + : JSONStructure(formatter), pool(pool_name) {} -} - -ceph::io_exerciser::json::OSDPoolGetRequest - ::OSDPoolGetRequest(JSONObj* obj, - std::shared_ptr formatter) : - JSONStructure(formatter) -{ +ceph::io_exerciser::json::OSDPoolGetRequest ::OSDPoolGetRequest( + JSONObj* obj, std::shared_ptr formatter) + : JSONStructure(formatter) { ceph::io_exerciser::json::OSDPoolGetRequest::decode_json(obj); } @@ -118,8 +94,7 @@ void ceph::io_exerciser::json::OSDPoolGetRequest::decode_json(JSONObj* 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()); @@ -128,48 +103,36 @@ void ceph::io_exerciser::json::OSDPoolGetRequest::dump() const formatter->close_section(); } -ceph::io_exerciser::json::OSDPoolGetReply - ::OSDPoolGetReply(std::shared_ptr formatter) : - JSONStructure(formatter) -{ - -} +ceph::io_exerciser::json::OSDPoolGetReply ::OSDPoolGetReply( + std::shared_ptr 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 formatter) : - JSONStructure(formatter), - name(profile_name) -{ +ceph::io_exerciser::json::OSDECProfileGetRequest ::OSDECProfileGetRequest( + const std::string& profile_name, std::shared_ptr formatter) + : JSONStructure(formatter), name(profile_name) {} -} - -ceph::io_exerciser::json::OSDECProfileGetRequest - ::OSDECProfileGetRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ - -} +ceph::io_exerciser::json::OSDECProfileGetRequest ::OSDECProfileGetRequest( + std::shared_ptr 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()); @@ -177,26 +140,20 @@ void ceph::io_exerciser::json::OSDECProfileGetRequest::dump() const formatter->close_section(); } -ceph::io_exerciser::json::OSDECProfileGetReply - ::OSDECProfileGetReply(std::shared_ptr formatter) : - JSONStructure(formatter) -{ - -} +ceph::io_exerciser::json::OSDECProfileGetReply ::OSDECProfileGetReply( + std::shared_ptr 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); @@ -204,24 +161,16 @@ void ceph::io_exerciser::json::OSDECProfileGetReply::decode_json(JSONObj* 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()); @@ -231,33 +180,22 @@ void ceph::io_exerciser::json::OSDECProfileGetReply::dump() const formatter->close_section(); } -ceph::io_exerciser::json::OSDECProfileSetRequest - ::OSDECProfileSetRequest(const std::string& name, - const std::vector& profile, - std::shared_ptr formatter) : - JSONStructure(formatter), - name(name), - profile(profile) -{ +ceph::io_exerciser::json::OSDECProfileSetRequest ::OSDECProfileSetRequest( + const std::string& name, const std::vector& profile, + std::shared_ptr formatter) + : JSONStructure(formatter), name(name), profile(profile) {} -} - -OSDECProfileSetRequest - ::OSDECProfileSetRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ +OSDECProfileSetRequest ::OSDECProfileSetRequest( + std::shared_ptr 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()); @@ -265,24 +203,18 @@ void OSDECProfileSetRequest::dump() const formatter->close_section(); } -OSDECPoolCreateRequest::OSDECPoolCreateRequest(const std::string& pool, - const std::string& erasure_code_profile, - std::shared_ptr 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 formatter) + : JSONStructure(formatter), + pool(pool), + erasure_code_profile(erasure_code_profile) {} -OSDECPoolCreateRequest - ::OSDECPoolCreateRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ -} +OSDECPoolCreateRequest ::OSDECPoolCreateRequest( + std::shared_ptr 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); @@ -291,8 +223,7 @@ void OSDECPoolCreateRequest::decode_json(JSONObj* 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()); @@ -305,28 +236,21 @@ void OSDECPoolCreateRequest::dump() const OSDSetRequest::OSDSetRequest(const std::string& key, const std::optional& yes_i_really_mean_it, - std::shared_ptr formatter) : - JSONStructure(formatter), - key(key), - yes_i_really_mean_it(yes_i_really_mean_it) -{ + std::shared_ptr formatter) + : JSONStructure(formatter), + key(key), + yes_i_really_mean_it(yes_i_really_mean_it) {} -} - -OSDSetRequest::OSDSetRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ -} +OSDSetRequest::OSDSetRequest(std::shared_ptr 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()); @@ -334,80 +258,62 @@ void OSDSetRequest::dump() const formatter->close_section(); } -BalancerOffRequest::BalancerOffRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ +BalancerOffRequest::BalancerOffRequest( + std::shared_ptr 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 formatter) : - JSONStructure(formatter) -{ - -} +BalancerStatusRequest ::BalancerStatusRequest( + std::shared_ptr 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 formatter) : - JSONStructure(formatter) -{ +BalancerStatusReply::BalancerStatusReply( + std::shared_ptr 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(); } @@ -415,24 +321,17 @@ ConfigSetRequest::ConfigSetRequest(const std::string& who, const std::string& name, const std::string& value, const std::optional& force, - std::shared_ptr formatter) : - JSONStructure(formatter), - who(who), - name(name), - value(value), - force(force) -{ - -} + std::shared_ptr formatter) + : JSONStructure(formatter), + who(who), + name(name), + value(value), + force(force) {} -ConfigSetRequest::ConfigSetRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ +ConfigSetRequest::ConfigSetRequest(std::shared_ptr 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); @@ -440,8 +339,7 @@ void ConfigSetRequest::decode_json(JSONObj* 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()); @@ -451,31 +349,27 @@ void ConfigSetRequest::dump() const formatter->close_section(); } -InjectECErrorRequest::InjectECErrorRequest(InjectOpType injectOpType, - const std::string& pool, - const std::string& objname, - int shardid, - const std::optional& type, - const std::optional& when, - const std::optional& duration, - std::shared_ptr 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& type, const std::optional& when, + const std::optional& duration, + std::shared_ptr 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; @@ -484,15 +378,11 @@ InjectECErrorRequest::InjectECErrorRequest(InjectOpType injectOpType, } } -InjectECErrorRequest - ::InjectECErrorRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ +InjectECErrorRequest ::InjectECErrorRequest( + std::shared_ptr 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()); @@ -504,8 +394,7 @@ void InjectECErrorRequest::dump() const 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); @@ -515,29 +404,24 @@ void InjectECErrorRequest::decode_json(JSONObj* obj) JSONDecoder::decode_json("duration", duration, obj); } - - -InjectECClearErrorRequest::InjectECClearErrorRequest(InjectOpType injectOpType, - const std::string& pool, - const std::string& objname, - int shardid, - const std::optional& type, - std::shared_ptr 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& type, + std::shared_ptr 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; @@ -546,15 +430,11 @@ InjectECClearErrorRequest::InjectECClearErrorRequest(InjectOpType injectOpType, } } -InjectECClearErrorRequest - ::InjectECClearErrorRequest(std::shared_ptr formatter) : - JSONStructure(formatter) -{ - -} +InjectECClearErrorRequest ::InjectECClearErrorRequest( + std::shared_ptr 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()); @@ -564,8 +444,7 @@ void InjectECClearErrorRequest::dump() const 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); diff --git a/src/common/io_exerciser/JsonStructures.h b/src/common/io_exerciser/JsonStructures.h index b439845b3ab2a..5a9f11e65ceac 100644 --- a/src/common/io_exerciser/JsonStructures.h +++ b/src/common/io_exerciser/JsonStructures.h @@ -2,9 +2,8 @@ #include #include -#include "include/types.h" - #include "OpType.h" +#include "include/types.h" /* Overview * @@ -17,305 +16,287 @@ class JSONObj; -namespace ceph -{ - namespace io_exerciser - { - namespace json - { - class JSONStructure - { - public: - JSONStructure(std::shared_ptr formatter - = std::make_shared(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; - - 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 - = std::make_shared(false)); - OSDMapRequest(std::shared_ptr formatter - = std::make_shared(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 - = std::make_shared(false)); - - epoch_t epoch; - std::string pool; - uint64_t pool_id; - std::string objname; - std::string raw_pgid; - std::string pgid; - std::vector up; - int up_primary; - std::vector 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 formatter = std::make_shared(false)); - OSDPoolGetRequest(JSONObj* obj, std::shared_ptr formatter = std::make_shared(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 formatter = std::make_shared(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 formatter = std::make_shared(false)); - OSDECProfileGetRequest(std::shared_ptr formatter = std::make_shared(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 formatter = std::make_shared(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& profile, - std::shared_ptr formatter - = std::make_shared(false)); - OSDECProfileSetRequest(std::shared_ptr formatter - = std::make_shared(false)); - - std::string prefix = "osd erasure-code-profile set"; - std::string name; - std::vector 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 - = std::make_shared(false)); - OSDECPoolCreateRequest(std::shared_ptr formatter - = std::make_shared(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& yes_i_really_mean_it - = std::nullopt, - std::shared_ptr formatter - = std::make_shared(false)); - OSDSetRequest(std::shared_ptr formatter - = std::make_shared(false)); - - std::string prefix = "osd set"; - std::string key; - std::optional 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 - = std::make_shared(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 - = std::make_shared(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 - = std::make_shared(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& force = std::nullopt, - std::shared_ptr formatter - = std::make_shared(false)); - ConfigSetRequest(std::shared_ptr formatter - = std::make_shared(false)); - - std::string prefix = "config set"; - std::string who; - std::string name; - std::string value; - std::optional 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& type, - const std::optional& when, - const std::optional& duration, - std::shared_ptr formatter - = std::make_shared(false)); - InjectECErrorRequest(std::shared_ptr formatter - = std::make_shared(false)); - - std::string prefix; - std::string pool; - std::string objname; - int shardid; - std::optional type; - std::optional when; - std::optional 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& type, - std::shared_ptr formatter - = std::make_shared(false)); - - InjectECClearErrorRequest(std::shared_ptr formatter - = std::make_shared(false)); - - std::string prefix; - std::string pool; - std::string objname; - int shardid; - std::optional 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 = + std::make_shared(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; + + 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 = + std::make_shared(false)); + OSDMapRequest(std::shared_ptr formatter = + std::make_shared(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 = + std::make_shared(false)); + + epoch_t epoch; + std::string pool; + uint64_t pool_id; + std::string objname; + std::string raw_pgid; + std::string pgid; + std::vector up; + int up_primary; + std::vector 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 formatter = + std::make_shared(false)); + OSDPoolGetRequest(JSONObj* obj, std::shared_ptr formatter = + std::make_shared(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 formatter = + std::make_shared(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 formatter = + std::make_shared(false)); + OSDECProfileGetRequest(std::shared_ptr formatter = + std::make_shared(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 formatter = + std::make_shared(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& profile, + std::shared_ptr formatter = + std::make_shared(false)); + OSDECProfileSetRequest(std::shared_ptr formatter = + std::make_shared(false)); + + std::string prefix = "osd erasure-code-profile set"; + std::string name; + std::vector 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 = + std::make_shared(false)); + OSDECPoolCreateRequest(std::shared_ptr formatter = + std::make_shared(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& yes_i_really_mean_it = std::nullopt, + std::shared_ptr formatter = + std::make_shared(false)); + OSDSetRequest(std::shared_ptr formatter = + std::make_shared(false)); + + std::string prefix = "osd set"; + std::string key; + std::optional 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 = + std::make_shared(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 = + std::make_shared(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 = + std::make_shared(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& force = std::nullopt, + std::shared_ptr formatter = + std::make_shared(false)); + ConfigSetRequest(std::shared_ptr formatter = + std::make_shared(false)); + + std::string prefix = "config set"; + std::string who; + std::string name; + std::string value; + std::optional 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& type, + const std::optional& when, + const std::optional& duration, + std::shared_ptr formatter = + std::make_shared(false)); + InjectECErrorRequest(std::shared_ptr formatter = + std::make_shared(false)); + + std::string prefix; + std::string pool; + std::string objname; + int shardid; + std::optional type; + std::optional when; + std::optional 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& type, + std::shared_ptr formatter = + std::make_shared(false)); + + InjectECClearErrorRequest(std::shared_ptr formatter = + std::make_shared(false)); + + std::string prefix; + std::string pool; + std::string objname; + int shardid; + std::optional type; + + void decode_json(JSONObj* obj) override; + void dump() const override; +}; +} // namespace json +} // namespace io_exerciser +} // namespace ceph \ No newline at end of file diff --git a/src/common/io_exerciser/Model.cc b/src/common/io_exerciser/Model.cc index 50812ecbb155d..6548e1eda7a80 100644 --- a/src/common/io_exerciser/Model.cc +++ b/src/common/io_exerciser/Model.cc @@ -4,25 +4,11 @@ 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 diff --git a/src/common/io_exerciser/Model.h b/src/common/io_exerciser/Model.h index 58d107409a654..9e421e79a78de 100644 --- a/src/common/io_exerciser/Model.h +++ b/src/common/io_exerciser/Model.h @@ -1,15 +1,13 @@ #pragma once -#include "IoOp.h" - #include -#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 * @@ -21,29 +19,27 @@ */ 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 diff --git a/src/common/io_exerciser/ObjectModel.cc b/src/common/io_exerciser/ObjectModel.cc index 4f2c295af7252..454d7254cf2a8 100644 --- a/src/common/io_exerciser/ObjectModel.cc +++ b/src/common/io_exerciser/ObjectModel.cc @@ -6,25 +6,20 @@ 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 ObjectModel::get_seed_offsets(int seed) const -{ +std::vector ObjectModel::get_seed_offsets(int seed) const { std::vector 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); } } @@ -32,8 +27,7 @@ std::vector ObjectModel::get_seed_offsets(int seed) const 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"; } @@ -48,166 +42,127 @@ std::string ObjectModel::to_string(int mask) const 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 ] - - (ReadWriteOp& 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 ] - - (ReadWriteOp 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 ] - - (ReadWriteOp 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](ReadWriteOp& 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](ReadWriteOp 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](ReadWriteOp 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(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(op); - verify_and_record_read_op(readOp); - } - break; - case OpType::Read2: - { - DoubleReadOp& readOp = static_cast(op); - verify_and_record_read_op(readOp); - } - break; - case OpType::Read3: - { - TripleReadOp& readOp = static_cast(op); - verify_and_record_read_op(readOp); - } - break; - - case OpType::Write: - { - ceph_assert(created); - SingleWriteOp& writeOp = static_cast(op); - verify_write_and_record_and_generate_seed(writeOp); - } - break; - case OpType::Write2: - { - DoubleWriteOp& writeOp = static_cast(op); - verify_write_and_record_and_generate_seed(writeOp); - } - break; - case OpType::Write3: - { - TripleWriteOp& writeOp = static_cast(op); - verify_write_and_record_and_generate_seed(writeOp); - } - break; - case OpType::FailedWrite: - { - ceph_assert(created); - SingleWriteOp& writeOp = static_cast(op); - verify_failed_write_and_record(writeOp); - } - break; - case OpType::FailedWrite2: - { - DoubleWriteOp& writeOp = static_cast(op); - verify_failed_write_and_record(writeOp); - } - break; - case OpType::FailedWrite3: - { - TripleWriteOp& writeOp = static_cast(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(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(op); + verify_and_record_read_op(readOp); + } break; + case OpType::Read2: { + DoubleReadOp& readOp = static_cast(op); + verify_and_record_read_op(readOp); + } break; + case OpType::Read3: { + TripleReadOp& readOp = static_cast(op); + verify_and_record_read_op(readOp); + } break; + + case OpType::Write: { + ceph_assert(created); + SingleWriteOp& writeOp = static_cast(op); + verify_write_and_record_and_generate_seed(writeOp); + } break; + case OpType::Write2: { + DoubleWriteOp& writeOp = static_cast(op); + verify_write_and_record_and_generate_seed(writeOp); + } break; + case OpType::Write3: { + TripleWriteOp& writeOp = static_cast(op); + verify_write_and_record_and_generate_seed(writeOp); + } break; + case OpType::FailedWrite: { + ceph_assert(created); + SingleWriteOp& writeOp = static_cast(op); + verify_failed_write_and_record(writeOp); + } break; + case OpType::FailedWrite2: { + DoubleWriteOp& writeOp = static_cast(op); + verify_failed_write_and_record(writeOp); + } break; + case OpType::FailedWrite3: { + TripleWriteOp& writeOp = static_cast(op); + verify_failed_write_and_record(writeOp); + } break; + default: + break; } } diff --git a/src/common/io_exerciser/ObjectModel.h b/src/common/io_exerciser/ObjectModel.h index 93c70f4142978..cad1307b84e30 100644 --- a/src/common/io_exerciser/ObjectModel.h +++ b/src/common/io_exerciser/ObjectModel.h @@ -14,40 +14,41 @@ */ namespace ceph { - namespace io_exerciser { - /* Model of an object to track its data contents */ - - class ObjectModel : public Model { - private: - bool created; - std::vector contents; - ceph::util::random_number_generator rng = - ceph::util::random_number_generator(); - - // 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 reads; - interval_set writes; - public: - ObjectModel(const std::string& oid, uint64_t block_size, int seed); - - int get_seed(uint64_t offset) const; - std::vector 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 contents; + ceph::util::random_number_generator rng = + ceph::util::random_number_generator(); + + // 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 reads; + interval_set writes; + + public: + ObjectModel(const std::string& oid, uint64_t block_size, int seed); + + int get_seed(uint64_t offset) const; + std::vector 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 diff --git a/src/common/io_exerciser/OpType.h b/src/common/io_exerciser/OpType.h index 84901b372c235..7cddb805e458c 100644 --- a/src/common/io_exerciser/OpType.h +++ b/src/common/io_exerciser/OpType.h @@ -1,7 +1,6 @@ #pragma once #include - #include /* Overview @@ -11,53 +10,45 @@ * */ -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 -{ - constexpr auto parse(format_parse_context& ctx) - { - return ctx.begin(); - } +struct fmt::formatter { + 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: diff --git a/src/common/io_exerciser/RadosIo.cc b/src/common/io_exerciser/RadosIo.cc index 03cb2d26d3f0c..048622ccde098 100644 --- a/src/common/io_exerciser/RadosIo.cc +++ b/src/common/io_exerciser/RadosIo.cc @@ -1,355 +1,306 @@ #include "RadosIo.h" -#include "DataGenerator.h" - #include #include -#include "common/ceph_json.h" +#include +#include "DataGenerator.h" #include "JsonStructures.h" - -#include +#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>& 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(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>& 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(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 RadosIo::AsyncOpInfo::AsyncOpInfo(const std::array& offset, - const std::array& length) : - offset(offset), length(length) -{ - -} + const std::array& 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(op).size; - std::shared_ptr> op_info - = std::make_shared>(std::array{0}, - std::array{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>(); - 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(op).size; + std::shared_ptr> op_info = + std::make_shared>(std::array{0}, + std::array{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>(); + 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](ReadWriteOp readOp) - { - auto op_info = std::make_shared>(readOp.offset, readOp.length); +void RadosIo::applyReadWriteOp(IoOp& op) { + auto applyReadOp = [this]( + ReadWriteOp readOp) { + auto op_info = + std::make_shared>(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](ReadWriteOp writeOp) - { - auto op_info = std::make_shared>(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]( + ReadWriteOp writeOp) { + auto op_info = + std::make_shared>(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](ReadWriteOp writeOp) - { - auto op_info = std::make_shared>(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]( + ReadWriteOp writeOp) { + auto op_info = + std::make_shared>(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(op); applyReadOp(readOp); break; - } - case OpType::Read2: - { - start_io(); - DoubleReadOp& readOp = static_cast(op); - applyReadOp(readOp); - break; - } - case OpType::Read3: - { - start_io(); - TripleReadOp& readOp = static_cast(op); - applyReadOp(readOp); - break; - } - case OpType::Write: - { - start_io(); - SingleWriteOp& writeOp = static_cast(op); - applyWriteOp(writeOp); - break; - } - case OpType::Write2: - { - start_io(); - DoubleWriteOp& writeOp = static_cast(op); - applyWriteOp(writeOp); - break; - } - case OpType::Write3: - { - start_io(); - TripleWriteOp& writeOp = static_cast(op); - applyWriteOp(writeOp); - break; - } + } + case OpType::Read2: { + start_io(); + DoubleReadOp& readOp = static_cast(op); + applyReadOp(readOp); + break; + } + case OpType::Read3: { + start_io(); + TripleReadOp& readOp = static_cast(op); + applyReadOp(readOp); + break; + } + case OpType::Write: { + start_io(); + SingleWriteOp& writeOp = static_cast(op); + applyWriteOp(writeOp); + break; + } + case OpType::Write2: { + start_io(); + DoubleWriteOp& writeOp = static_cast(op); + applyWriteOp(writeOp); + break; + } + case OpType::Write3: { + start_io(); + TripleWriteOp& writeOp = static_cast(op); + applyWriteOp(writeOp); + break; + } - case OpType::FailedWrite: - { - start_io(); - SingleFailedWriteOp& writeOp = static_cast(op); - applyFailedWriteOp(writeOp); - break; - } - case OpType::FailedWrite2: - { - start_io(); - DoubleFailedWriteOp& writeOp = static_cast(op); - applyFailedWriteOp(writeOp); - break; - } - case OpType::FailedWrite3: - { - start_io(); - TripleFailedWriteOp& writeOp = static_cast(op); - applyFailedWriteOp(writeOp); - break; - } + case OpType::FailedWrite: { + start_io(); + SingleFailedWriteOp& writeOp = static_cast(op); + applyFailedWriteOp(writeOp); + break; + } + case OpType::FailedWrite2: { + start_io(); + DoubleFailedWriteOp& writeOp = static_cast(op); + applyFailedWriteOp(writeOp); + break; + } + case OpType::FailedWrite3: { + start_io(); + TripleFailedWriteOp& writeOp = static_cast(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(false); int osd = -1; std::vector 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; @@ -364,127 +315,94 @@ void RadosIo::applyInjectOp(IoOp& op) InjectOpType injectOpType; - switch(op.getOpType()) - { - case OpType::InjectReadError: - { + switch (op.getOpType()) { + case OpType::InjectReadError: { InjectReadErrorOp& errorOp = static_cast(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(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(op); + case OpType::ClearReadErrorInject: { + ClearReadErrorInjectOp& errorOp = + static_cast(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(op); + case OpType::ClearWriteErrorInject: { + ClearReadErrorInjectOp& errorOp = + static_cast(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 diff --git a/src/common/io_exerciser/RadosIo.h b/src/common/io_exerciser/RadosIo.h index 9e5316b7a738e..a5c66ad4768ab 100644 --- a/src/common/io_exerciser/RadosIo.h +++ b/src/common/io_exerciser/RadosIo.h @@ -10,70 +10,65 @@ * 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 om; - std::unique_ptr db; - std::string pool; - std::optional> 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 om; + std::unique_ptr db; + std::string pool; + std::optional> 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>& 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>& 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 - class AsyncOpInfo { - public: - librados::ObjectReadOperation rop; - librados::ObjectWriteOperation wop; - std::array bufferlist; - std::array offset; - std::array length; + template + class AsyncOpInfo { + public: + librados::ObjectReadOperation rop; + librados::ObjectWriteOperation wop; + std::array bufferlist; + std::array offset; + std::array length; - AsyncOpInfo(const std::array& offset = {}, - const std::array& length = {}); - ~AsyncOpInfo() = default; - }; + AsyncOpInfo(const std::array& offset = {}, + const std::array& 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 diff --git a/src/test/osd/ceph_test_rados_io_sequence.cc b/src/test/osd/ceph_test_rados_io_sequence.cc index 18852b6aa3168..da2218a47c250 100644 --- a/src/test/osd/ceph_test_rados_io_sequence.cc +++ b/src/test/osd/ceph_test_rados_io_sequence.cc @@ -1,18 +1,13 @@ #include "ceph_test_rados_io_sequence.h" +#include #include #include -#include - -#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" @@ -21,17 +16,20 @@ #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 @@ -53,55 +51,52 @@ using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp; using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp; namespace { - struct Size {}; - void validate(boost::any& v, const std::vector& 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& 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& 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{first,second}); +struct Pair {}; +void validate(boost::any& v, const std::vector& 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{first, second}); +} - struct PluginString {}; - void validate(boost::any& v, const std::vector& 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& 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", @@ -148,110 +143,83 @@ namespace { "\t\t read3|write3|failedwrite3 ", "\t\t injecterror ", "\t\t clearinject ", - "\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(), - "test specified sequence") - ("seed", po::value(), - "seed for whole test") - ("seqseed", po::value(), - "seed for sequence") - ("blocksize,b", po::value(), - "block size (default 2048)") - ("chunksize,c", po::value(), - "chunk size (default 4096)") - ("pool,p", po::value(), - "pool name") - ("object,o", po::value()->default_value("test"), - "object name") - ("km", po::value(), - "k,m EC pool profile (default 2,2)") - ("plugin", po::value(), - "EC plugin (isa or jerasure)") - ("objectsize", po::value(), - "min,max object size in blocks (default 1,32)") - ("threads,t", po::value(), - "number of threads of I/O per object (default 1)") - ("parallel,p", po::value()->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 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(), "test specified sequence")( + "seed", po::value(), "seed for whole test")( + "seqseed", po::value(), "seed for sequence")( + "blocksize,b", po::value(), "block size (default 2048)")( + "chunksize,c", po::value(), "chunk size (default 4096)")( + "pool,p", po::value(), "pool name")( + "object,o", po::value()->default_value("test"), + "object name")("km", po::value(), + "k,m EC pool profile (default 2,2)")( + "plugin", po::value(), "EC plugin (isa or jerasure)")( + "objectsize", po::value(), + "min,max object size in blocks (default 1,32)")( + "threads,t", po::value(), + "number of threads of I/O per object (default 1)")( + "parallel,p", po::value()->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 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 & Ts> -ceph::io_sequence::tester::ProgramOptionSelector - ::ProgramOptionSelector(ceph::util::random_number_generator& 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:: + ProgramOptionSelector(ceph::util::random_number_generator& 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(); } @@ -262,134 +230,88 @@ ceph::io_sequence::tester::ProgramOptionSelector } template & Ts> -bool ceph::io_sequence::tester::ProgramOptionSelector::isForced() -{ +bool ceph::io_sequence::tester::ProgramOptionSelector::isForced() { return force_value.has_value(); } template & Ts> -const T ceph::io_sequence::tester::ProgramOptionSelector::choose() -{ +const T ceph::io_sequence::tester::ProgramOptionSelector::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& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "objectsize", true, true) -{ -} - - + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "objectsize", true, true) {} ceph::io_sequence::tester::SelectBlockSize::SelectBlockSize( - ceph::util::random_number_generator& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "blocksize", true, true) -{ -} - - + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "blocksize", true, true) {} ceph::io_sequence::tester::SelectNumThreads::SelectNumThreads( - ceph::util::random_number_generator& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "threads", true, true) -{ -} - - + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "threads", true, true) {} ceph::io_sequence::tester::SelectSeqRange::SelectSeqRange( - ceph::util::random_number_generator& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "sequence", false, false) -{ + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "sequence", false, false) { if (vm.count(option_name)) { ceph::io_exerciser::Sequence s = - static_cast(vm["sequence"].as()); + static_cast(vm["sequence"].as()); 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::make_pair(s, ++e)); + force_value = std::make_optional< + std::pair>( + std::make_pair(s, ++e)); } } -const std::pair - ceph::io_sequence::tester::SelectSeqRange::choose() { - if (force_value.has_value()) - { +const std::pair +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& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "km", true, true) -{ -} - - + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "km", true, true) {} ceph::io_sequence::tester::SelectErasurePlugin::SelectErasurePlugin( - ceph::util::random_number_generator& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "plugin", true, false) -{ -} - - + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "plugin", true, false) {} ceph::io_sequence::tester::SelectErasureChunkSize::SelectErasureChunkSize( - ceph::util::random_number_generator& rng, - po::variables_map vm) - : ProgramOptionSelector(rng, vm, "chunksize", true, false) -{ -} - - + ceph::util::random_number_generator& rng, po::variables_map vm) + : ProgramOptionSelector(rng, vm, "chunksize", true, false) {} ceph::io_sequence::tester::SelectECPool::SelectECPool( - ceph::util::random_number_generator& 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& 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(); @@ -397,16 +319,17 @@ ceph::io_sequence::tester::SelectECPool::SelectECPool( } } -const std::string ceph::io_sequence::tester::SelectECPool::choose() -{ - std::pair value; +const std::string ceph::io_sequence::tester::SelectECPool::choose() { + std::pair value; if (!skm.isForced() && force_value.has_value()) { int rc; bufferlist inbl, outbl; auto formatter = std::make_shared(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; @@ -416,8 +339,10 @@ const std::string ceph::io_sequence::tester::SelectECPool::choose() 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()); @@ -437,62 +362,55 @@ const std::string ceph::io_sequence::tester::SelectECPool::choose() 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(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; @@ -504,70 +422,47 @@ void ceph::io_sequence::tester::SelectECPool::create_pool( 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& rng, - ceph::mutex& lock, - ceph::condition_variable& cond, - bool dryrun, - bool verbose, - std::optional 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& rng, ceph::mutex& lock, + ceph::condition_variable& cond, bool dryrun, bool verbose, + std::optional seqseed, bool testrecovery) + : rng(rng), verbose(verbose), seqseed(seqseed), testrecovery(testrecovery) { if (dryrun) { - exerciser_model = std::make_unique(oid, - sbs.choose(), - rng()); + exerciser_model = std::make_unique( + oid, sbs.choose(), rng()); } else { const std::string pool = spo.choose(); poolK = spo.getChosenK(); @@ -579,13 +474,12 @@ ceph::io_sequence::tester::TestObject::TestObject( const std::string oid, std::optional> 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; @@ -597,136 +491,97 @@ ceph::io_sequence::tester::TestObject::TestObject( const std::string oid, cached_shard_order = reply.acting; } - exerciser_model = std::make_unique(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( + 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() - << " ==" <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() - << " ==" <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() : time(nullptr)), - rng(ceph::util::random_number_generator(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() : time(nullptr)), + rng(ceph::util::random_number_generator(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"); @@ -746,18 +601,16 @@ ceph::io_sequence::tester::TestRunner::TestRunner(po::variables_map& vm, 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(); @@ -766,52 +619,40 @@ ceph::io_sequence::tester::TestRunner::~TestRunner() } } -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 obj_size_range = sos.choose(); + std::pair obj_size_range = sos.choose(); ceph::io_exerciser::Sequence s = ceph::io_exerciser::Sequence::SEQUENCE_BEGIN; std::unique_ptr 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); @@ -820,40 +661,33 @@ std::string ceph::io_sequence::tester::TestRunner::get_token() return std::string(*tokens++); } -std::optional ceph::io_sequence::tester::TestRunner - ::get_optional_token() -{ +std::optional +ceph::io_sequence::tester::TestRunner ::get_optional_token() { std::optional 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 ceph::io_sequence::tester::TestRunner - ::get_optional_numeric_token() -{ +std::optional +ceph::io_sequence::tester::TestRunner ::get_optional_numeric_token() { std::string parse_error; std::optional 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; } @@ -861,51 +695,37 @@ std::optional ceph::io_sequence::tester::TestRunner return std::optional(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 ioop; std::unique_ptr model; - if (dryrun) - { - model = std::make_unique(object_name, - sbs.choose(), - rng()); - } - else - { + if (dryrun) { + model = std::make_unique( + 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; @@ -915,172 +735,124 @@ bool ceph::io_sequence::tester::TestRunner::run_interactive_test() ceph::io_exerciser::json::OSDMapReply reply{}; reply.decode_json(&p); - model = std::make_unique(rados, asio, pool, - object_name, reply.acting, - sbs.choose(), rng(), - 1, // 1 thread - lock, cond); + model = std::make_unique( + 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 type = get_optional_numeric_token(); std::optional when = get_optional_numeric_token(); std::optional 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 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); } @@ -1090,11 +862,10 @@ bool ceph::io_sequence::tester::TestRunner::run_interactive_test() 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> test_objects; + std::vector> + test_objects; for (int obj = 0; obj < num_objects; obj++) { std::string name; @@ -1104,18 +875,11 @@ bool ceph::io_sequence::tester::TestRunner::run_automated_test() name = object_name + std::to_string(obj); } test_objects.push_back( - std::make_shared( - name, - rados, asio, - sbs, spo, sos, snt, ssr, - rng, lock, cond, - dryrun, verbose, - seqseed, testrecovery - ) - ); + std::make_shared( + name, rados, asio, sbs, spo, sos, snt, ssr, rng, lock, cond, dryrun, + verbose, seqseed, testrecovery)); } - if (!dryrun) - { + if (!dryrun) { rados.wait_for_latest_osdmap(); } @@ -1126,39 +890,31 @@ bool ceph::io_sequence::tester::TestRunner::run_automated_test() 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 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 to = *obj; - if (!to->finished()) - { + if (!to->finished()) { need_wait = !to->readyForIo(); - if (!need_wait) - { + if (!need_wait) { break; } } @@ -1168,8 +924,7 @@ bool ceph::io_sequence::tester::TestRunner::run_automated_test() } 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 to = *obj; total_io += to->get_num_io(); ceph_assert(to->finished()); @@ -1179,18 +934,16 @@ bool ceph::io_sequence::tester::TestRunner::run_automated_test() 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; } @@ -1205,7 +958,7 @@ int main(int argc, char **argv) std::unique_ptr runner; try { runner = std::make_unique(vm, rados); - } catch(const po::error& e) { + } catch (const po::error& e) { return 1; } runner->run_test(); diff --git a/src/test/osd/ceph_test_rados_io_sequence.h b/src/test/osd/ceph_test_rados_io_sequence.h index 265fa3e23a46f..c06c597f7840e 100644 --- a/src/test/osd/ceph_test_rados_io_sequence.h +++ b/src/test/osd/ceph_test_rados_io_sequence.h @@ -1,16 +1,14 @@ +#include +#include #include -#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 @@ -21,18 +19,18 @@ /* 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. @@ -62,323 +60,277 @@ 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,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 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 threadCountChoices = {{ - 1, // Default - 2, - 4, - 8 - }}; - - // Choices for EC k+m profile - inline constexpr int kmSize = 6; - inline constexpr std::array, 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 chunkSizeChoices = {{ - 4*1024, - 64*1024, - 256*1024 - }}; - - // Choices for plugin - inline constexpr int pluginListSize = 2; - inline constexpr std::array pluginChoices = {{ - "jerasure", - "isa" - }}; - - inline constexpr std::array, - 0> sequencePairs = {{}}; - - inline constexpr std::array poolChoices = {{}}; - - template & Ts> - class ProgramOptionSelector - { - public: - ProgramOptionSelector(ceph::util::random_number_generator& 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& rng; - static constexpr std::array choices = Ts; - - std::optional force_value; - std::optional first_value; - - std::string option_name; - }; - - class SelectObjectSize - : public ProgramOptionSelector, - io_sequence::tester::objectSizeSize, - io_sequence::tester::objectSizeChoices> - { - public: - SelectObjectSize(ceph::util::random_number_generator& rng, - po::variables_map vm); - }; - - class SelectBlockSize - : public ProgramOptionSelector - { - public: - SelectBlockSize(ceph::util::random_number_generator& rng, - po::variables_map vm); - }; - - class SelectNumThreads - : public ProgramOptionSelector - { - public: - SelectNumThreads(ceph::util::random_number_generator& rng, - po::variables_map vm); - }; - - class SelectSeqRange - : public ProgramOptionSelector, - 0, io_sequence::tester::sequencePairs> - { - public: - SelectSeqRange(ceph::util::random_number_generator& rng, - po::variables_map vm); - - const std::pair choose() override; - }; - - class SelectErasureKM - : public ProgramOptionSelector, - io_sequence::tester::kmSize, - io_sequence::tester::kmChoices> - { - public: - SelectErasureKM(ceph::util::random_number_generator& rng, +namespace ceph { +namespace io_sequence::tester { +// Choices for min and max object size +inline constexpr size_t objectSizeSize = 10; +inline constexpr std::array, 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 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 threadCountChoices = { + {1, // Default + 2, 4, 8}}; + +// Choices for EC k+m profile +inline constexpr int kmSize = 6; +inline constexpr std::array, 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 chunkSizeChoices = { + {4 * 1024, 64 * 1024, 256 * 1024}}; + +// Choices for plugin +inline constexpr int pluginListSize = 2; +inline constexpr std::array pluginChoices = { + {"jerasure", "isa"}}; + +inline constexpr std::array< + std::pair, 0> + sequencePairs = {{}}; + +inline constexpr std::array poolChoices = {{}}; + +template & Ts> +class ProgramOptionSelector { + public: + ProgramOptionSelector(ceph::util::random_number_generator& 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& rng; + static constexpr std::array choices = Ts; + + std::optional force_value; + std::optional first_value; + + std::string option_name; +}; + +class SelectObjectSize + : public ProgramOptionSelector, + io_sequence::tester::objectSizeSize, + io_sequence::tester::objectSizeChoices> { + public: + SelectObjectSize(ceph::util::random_number_generator& rng, + po::variables_map vm); +}; + +class SelectBlockSize + : public ProgramOptionSelector { + public: + SelectBlockSize(ceph::util::random_number_generator& rng, + po::variables_map vm); +}; + +class SelectNumThreads + : public ProgramOptionSelector { + public: + SelectNumThreads(ceph::util::random_number_generator& rng, + po::variables_map vm); +}; + +class SelectSeqRange + : public ProgramOptionSelector< + std::pair, + 0, io_sequence::tester::sequencePairs> { + public: + SelectSeqRange(ceph::util::random_number_generator& rng, + po::variables_map vm); + + const std::pair + choose() override; +}; + +class SelectErasureKM + : public ProgramOptionSelector, + io_sequence::tester::kmSize, + io_sequence::tester::kmChoices> { + public: + SelectErasureKM(ceph::util::random_number_generator& rng, + po::variables_map vm); +}; + +class SelectErasurePlugin + : public ProgramOptionSelector { + public: + SelectErasurePlugin(ceph::util::random_number_generator& rng, po::variables_map vm); - }; - - class SelectErasurePlugin - : public ProgramOptionSelector - { - public: - SelectErasurePlugin(ceph::util::random_number_generator& rng, - po::variables_map vm); - }; - - class SelectErasureChunkSize - : public ProgramOptionSelector - { - public: - SelectErasureChunkSize(ceph::util::random_number_generator& rng, - po::variables_map vm); - }; - - class SelectECPool - : public ProgramOptionSelector - { - public: - SelectECPool(ceph::util::random_number_generator& 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& rng, - ceph::mutex& lock, - ceph::condition_variable& cond, - bool dryrun, - bool verbose, - std::optional seqseed, - bool testRecovery); - - int get_num_io(); - bool readyForIo(); - bool next(); - bool finished(); - - protected: - std::unique_ptr exerciser_model; - std::pair obj_size_range; - std::pair seq_range; - ceph::io_exerciser::Sequence curseq; - std::unique_ptr seq; - std::unique_ptr op; - bool done; - ceph::util::random_number_generator& rng; - bool verbose; - std::optional 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 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> guard; - ceph::mutex lock = ceph::make_mutex("RadosIo::lock"); - ceph::condition_variable cond; - - bool input_valid; - - bool verbose; - bool dryrun; - std::optional 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 get_optional_token(); - uint64_t get_numeric_token(); - std::optional get_optional_numeric_token(); - - bool run_automated_test(); - - bool run_interactive_test(); - - void help(); - void list_sequence(bool testrecovery); - }; - } -} +}; + +class SelectErasureChunkSize + : public ProgramOptionSelector { + public: + SelectErasureChunkSize(ceph::util::random_number_generator& rng, + po::variables_map vm); +}; + +class SelectECPool + : public ProgramOptionSelector { + public: + SelectECPool(ceph::util::random_number_generator& 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& rng, ceph::mutex& lock, + ceph::condition_variable& cond, bool dryrun, bool verbose, + std::optional seqseed, bool testRecovery); + + int get_num_io(); + bool readyForIo(); + bool next(); + bool finished(); + + protected: + std::unique_ptr exerciser_model; + std::pair obj_size_range; + std::pair + seq_range; + ceph::io_exerciser::Sequence curseq; + std::unique_ptr seq; + std::unique_ptr op; + bool done; + ceph::util::random_number_generator& rng; + bool verbose; + std::optional 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 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> + guard; + ceph::mutex lock = ceph::make_mutex("RadosIo::lock"); + ceph::condition_variable cond; + + bool input_valid; + + bool verbose; + bool dryrun; + std::optional 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 get_optional_token(); + uint64_t get_numeric_token(); + std::optional 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 -- 2.39.5