#include "common/debug.h"
#include "common/dout.h"
+#include "fmt/format.h"
+#include "fmt/ranges.h"
+
#include <chrono>
#include <iostream>
#include <stdexcept>
using HeaderedSeededRandomGenerator = ceph::io_exerciser::data_generation
::HeaderedSeededRandomGenerator;
-std::mutex DataGenerator::DataGenerationSingleton::m_mutex;
-DataGenerator::DataGenerationSingleton
- DataGenerator::DataGenerationSingleton::m_singletonInstance =
- DataGenerator::DataGenerationSingleton();
-
std::unique_ptr<DataGenerator> DataGenerator::create_generator(
GenerationType generationType, const ObjectModel& model)
{
return nullptr;
}
-DataGenerator::DataGenerationSingleton::DataGenerationSingleton()
-{
- m_created = false;
-}
-
-DataGenerator::DataGenerationSingleton
- ::DataGenerationSingleton(uint64_t unique_id)
-{
- m_uniqueId = unique_id;
- m_created = true;
-}
-
-const DataGenerator::DataGenerationSingleton&
-DataGenerator::DataGenerationSingleton::createSpecificInstance(uint64_t unique_id)
-{
- std::scoped_lock lock(m_mutex);
- ceph_assert(!m_singletonInstance.m_created);
- m_singletonInstance = DataGenerationSingleton(unique_id);
-
- return m_singletonInstance;
-}
-
-const DataGenerator::DataGenerationSingleton&
- DataGenerator::DataGenerationSingleton::getInstance()
-{
- if (!m_singletonInstance.m_created)
- {
- std::scoped_lock lock(m_mutex);
- if (!m_singletonInstance.m_created)
- {
- std::mt19937_64 random_generator =
- std::mt19937_64(duration_cast<std::chrono::milliseconds>(
- std::chrono::system_clock::now().time_since_epoch()).count());
- m_singletonInstance = DataGenerator::DataGenerationSingleton(random_generator());
- }
- }
- return m_singletonInstance;
-}
-
-const uint64_t DataGenerator::DataGenerationSingleton::getUniqueId()
-{
- return getInstance().m_uniqueId;
-}
-
-void DataGenerator::generate_wrong_data(uint64_t offset, uint64_t length,
- bufferlist& retlist)
+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++)
- {
+ {
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)
{
- ceph::bufferlist comparison_list;
- generate_data(offset, length, comparison_list);
- return bufferlist.contents_equal(comparison_list);
+ return bufferlist.contents_equal(generate_data(offset, length));
}
-#include <bitset>
-
ceph::bufferptr SeededRandomGenerator::generate_block(uint64_t block_offset)
{
uint64_t block_size = m_model.get_block_size();
char buffer[block_size];
-
+
std::mt19937_64 random_generator(m_model.get_seed(block_offset));
uint64_t rand1 = random_generator();
uint64_t rand2 = random_generator();
return ceph::bufferptr(buffer, block_size);
}
-void SeededRandomGenerator::generate_data(uint64_t offset, uint64_t length,
- bufferlist& retlist)
+ceph::bufferptr SeededRandomGenerator::generate_wrong_block(uint64_t block_offset)
+{
+ uint64_t block_size = m_model.get_block_size();
+ char buffer[block_size];
+
+ std::mt19937_64 random_generator(m_model.get_seed(block_offset));
+ uint64_t rand1 = random_generator() - 1;
+ uint64_t rand2 = random_generator() + 1;
+
+ constexpr size_t generation_length = sizeof(uint64_t);
+
+ 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)
+ {
+ 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)
+ {
+ std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes);
+ }
+
+ return ceph::bufferptr(buffer, block_size);
+}
+
+bufferlist SeededRandomGenerator::generate_data(uint64_t offset, uint64_t length)
{
- ceph_assert(retlist.length() == 0);
+ bufferlist retlist;
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 retlist;
+
+ for (uint64_t block_offset = offset; block_offset < offset + length; block_offset++)
+ {
+ retlist.append(generate_wrong_block(block_offset));
+ }
+
+ return retlist;
+}
+
+HeaderedSeededRandomGenerator
+ ::HeaderedSeededRandomGenerator(const ObjectModel& model,
+ std::optional<uint64_t> unique_run_id) :
+ SeededRandomGenerator(model),
+ unique_run_id(unique_run_id.value_or(generate_unique_run_id()))
+{
+
+}
+
+uint64_t HeaderedSeededRandomGenerator::generate_unique_run_id()
+{
+ std::mt19937_64 random_generator =
+ std::mt19937_64(duration_cast<std::chrono::milliseconds>(
+ std::chrono::system_clock::now().time_since_epoch()).count());
+
+ return random_generator();
}
ceph::bufferptr HeaderedSeededRandomGenerator::generate_block(uint64_t block_offset)
{
- UniqueIdBytes unique_run_id = DataGenerator::DataGenerationSingleton::getUniqueId();
SeedBytes seed = m_model.get_seed(block_offset);
TimeBytes current_time = duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
ceph::bufferptr bufferptr = SeededRandomGenerator::generate_block(block_offset);
- std::memcpy(bufferptr.c_str(), &unique_run_id + uniqueIdStart(), 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;
}
-void HeaderedSeededRandomGenerator::generate_wrong_data(uint64_t offset,
- uint64_t length,
- bufferlist& retlist)
+ceph::bufferptr HeaderedSeededRandomGenerator::generate_wrong_block(uint64_t block_offset)
{
- ceph_assert(retlist.length() == 0);
- ceph_assert(m_model.get_block_size() >= headerLength());
-
- ceph::bufferptr bufferptr;
- for (uint64_t block_offset = offset; block_offset < offset + length; block_offset++)
- {
- UniqueIdBytes unique_run_id = DataGenerator::DataGenerationSingleton::getUniqueId();
- SeedBytes seed = m_model.get_seed(block_offset-1);
- TimeBytes current_time = duration_cast<std::chrono::milliseconds>(
- std::chrono::system_clock::now().time_since_epoch()).count();
-
- bufferptr = generate_block(block_offset-1);
-
- std::memcpy(bufferptr.c_str(), &unique_run_id + uniqueIdStart(), uniqueIdLength());
- std::memcpy(bufferptr.c_str() + seedStart(), &seed, seedLength());
- std::memcpy(bufferptr.c_str() + timeStart(), ¤t_time, timeLength());
-
- retlist.append(std::move(bufferptr));
- }
+ return HeaderedSeededRandomGenerator::generate_block(block_offset % 8);
}
const HeaderedSeededRandomGenerator::UniqueIdBytes
bool HeaderedSeededRandomGenerator::validate_block(uint64_t block_offset,
const char* buffer_start)
{
- // We validate the block matches what we generate byte for byte, however we ignore the time section of the header
+ // 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(),
m_model.get_block_size() - timeEnd()) == 0 : valid;
return valid;
}
-
+
const HeaderedSeededRandomGenerator::ErrorType
HeaderedSeededRandomGenerator::getErrorTypeForBlock(uint64_t read_offset,
uint64_t block_offset,
{
UniqueIdBytes read_unique_run_id = readUniqueRunId(block_offset - read_offset,
bufferlist);
- if (DataGenerationSingleton::getUniqueId() != read_unique_run_id)
+ if (unique_run_id != read_unique_run_id)
{
return ErrorType::RUN_ID_MISMATCH;
}
if (blockError == ErrorType::DATA_MISMATCH || blockError == ErrorType::UNKNOWN)
{
- read_time = readDateTime(block_offset, bufferlist);
+ read_time = readDateTime(block_offset - read_offset, bufferlist);
std::chrono::system_clock::time_point time_point{std::chrono::milliseconds{read_time}};
ttp = std::chrono::system_clock::to_time_t(time_point);
generate_block(block_offset).c_str(),
m_model.get_block_size() - bodyStart());
}
- std::stringstream ss;
+
+ std::string error_string;
switch(blockError)
{
case ErrorType::RUN_ID_MISMATCH:
{
UniqueIdBytes read_unique_run_id = readUniqueRunId((block_offset - read_offset),
bufferlist);
- ss << "Header (Run ID) mismatch detected at block " << block_offset
- << " (byte offset " << block_offset * m_model.get_block_size() << ")."
- << " Header expected run id " << DataGenerationSingleton::getUniqueId()
- << " but found id " << read_unique_run_id
- << ". Block data corrupt or not written from this instance of this application.";
+ 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)
{
- ss << "Data (Seed) mismatch detected at block " << block_offset
- << " (byte offset " << block_offset * m_model.get_block_size() << ")."
- << " Header expected seed " << m_model.get_seed(block_offset)
- << " but found seed " << read_seed
- << ". Read data was not from any other recognised block in the object.";
+ 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
{
- ss << "Data (Seed) mismatch detected at block " << block_offset
- << " (byte offset " << block_offset * m_model.get_block_size() << ")."
- << " Header expected seed " << m_model.get_seed(block_offset)
- << " but found seed " << read_seed
- << ". Read data was from a different block(s): "
- << m_model.get_seed_offsets(read_seed);
+ std::vector<int> seed_offsets = m_model.get_seed_offsets(read_seed);
+ error_string = fmt::format("Data (Seed) mismatch detected at block {}"
+ " (byte offset {}). Header expected seed {} but found seed {}."
+ " Read data was from a different block(s): {}",
+ block_offset,
+ block_offset * m_model.get_block_size(),
+ m_model.get_seed(block_offset),
+ read_seed,
+ fmt::join(seed_offsets.begin(), seed_offsets.end(), ""));
}
}
break;
case ErrorType::DATA_MISMATCH:
{
- ss << "Data (Body) mismatch detected at block " << block_offset
- << " (byte offset " << block_offset * m_model.get_block_size() << ")."
- << " Header data matches, data body does not."
- << " Data written at " << std::ctime(&ttp)
- << "\nExpected data: " << std::endl;
- ss << std::hex << std::setw(2) << std::setfill('0');
- for (uint64_t i = headerLength();
- i < m_model.get_block_size() - headerLength(); i++)
- {
- ss << static_cast<int>(generated_bytes[i]);
- }
- dout(0) << dendl;
- ss << " Read data: " << std::endl;
- for (uint64_t i = headerLength();
- i < m_model.get_block_size() - headerLength(); i++)
- {
- ss << static_cast<int>(read_bytes[i]);
- }
+ 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(read_bytes, read_bytes + m_model.get_block_size(), ""));
}
break;
case ErrorType::DATA_NOT_FOUND:
{
uint64_t bufferlist_length = bufferlist.to_str().size();
- ss << "Data (Body) could not be read at block " << block_offset
- << " (byte offset " << block_offset * m_model.get_block_size() << ")"
- << " offset in bufferlist returned from read: " << (block_offset - read_offset)
- << " (" << (block_offset - read_offset) * m_model.get_block_size() << " bytes)."
- << " Returned bufferlist length: " << bufferlist_length;
+ 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;
default:
{
- ss << "Data mismatch detected at block " << block_offset
- << " (byte offset " << block_offset * m_model.get_block_size() << ")."
- << "\nExpected data: " << std::endl;
- ss << std::hex << std::setw(2) << std::setfill('0');
- for (uint64_t i = 0; i < m_model.get_block_size(); i++)
- {
- ss << static_cast<int>(generated_bytes[i]);
- }
- ss << std::endl << "Read data: " << std::endl;
- for (uint64_t i = 0; i < m_model.get_block_size(); i++)
- {
- ss << static_cast<int>(read_bytes[i]);
- }
+ 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;
}
- dout(0) << ss.str() << dendl;
+ dout(0) << error_string << dendl;
}
void HeaderedSeededRandomGenerator
{
uint64_t range_start = start_block_offset;
uint64_t range_length = 0;
- UniqueIdBytes initial_read_unique_run_id = readUniqueRunId(start_block_offset,
+ 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);
- UniqueIdBytes read_unique_run_id = readUniqueRunId(i, 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))
{
}
else if (range_length > 1)
{
- dout(0) << "Data (Run ID) Mismatch detected from block " << range_start
- << " (" << range_start * m_model.get_block_size() << " bytes)"
- << " and spanning a range of " << range_length << " blocks"
- << "(" << range_length * m_model.get_block_size() << " bytes). "
- << "Expected run id " << DataGenerationSingleton::getUniqueId()
- << " for range but found id " << initial_read_unique_run_id
- << " for all blocks in range. "
- << "Block data corrupt or not written from this instance of this application."
- << dendl;
+ 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;
}
else
{
- range_length++;
+ range_length++;
}
}
}
else if (range_length > 1)
{
- dout(0) << "Data (Run ID) Mismatch detected from block " << range_start
- << " (" << range_start * m_model.get_block_size() << " bytes) "
- << "and spanning a range of " << range_length << " blocks "
- << "(" << range_length * m_model.get_block_size() << " bytes). "
- << "Expected run id " << DataGenerationSingleton::getUniqueId()
- << " for range but found id " << initial_read_unique_run_id
- << " for all blocks in range. "
- << "Block data corrupt or not written from this instance of this application."
+ 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;
}
}
// Assert here if needed, as we can't support values
// that can't be converted to a signed integer.
ceph_assert(m_model.get_block_size() < (std::numeric_limits<uint64_t>::max() / 2));
- int64_t range_offset = 0;
+ std::optional<int64_t> range_offset = 0;
for (uint64_t i = start_block_offset;
i < start_block_offset + range_length_in_blocks; i++)
{
ceph_assert(getErrorTypeForBlock(read_offset, i, bufferlist)
== ErrorType::SEED_MISMATCH);
- SeedBytes read_seed = readSeed(i, bufferlist);
+ SeedBytes read_seed = readSeed(i - read_offset, bufferlist);
std::vector<int> seed_found_offsets = m_model.get_seed_offsets(read_seed);
if ((seed_found_offsets.size() == 1 &&
- (static_cast<int64_t>(seed_found_offsets.front() - i) == range_offset)) ||
+ (static_cast<int64_t>(seed_found_offsets.front() - i) == range_offset)) ||
range_length == 0)
{
if (range_length == 0)
{
range_start = i;
- range_offset = seed_found_offsets.front() - i;
+ if (seed_found_offsets.size() > 0)
+ {
+ range_offset = seed_found_offsets.front() - i;
+ }
+ else
+ {
+ range_offset = std::nullopt;
+ }
}
range_length++;
}
{
printDebugInformationForBlock(read_offset, i - 1, bufferlist);
}
- else if (range_length > 1)
+ else if (range_length > 1 && range_offset.has_value())
{
- dout(0) << "Data (Seed) Mismatch detected from block " << range_start
- << " (" << range_start * m_model.get_block_size() << " bytes) "
- << "and spanning a range of " << range_length << " blocks "
- << "(" << range_length * m_model.get_block_size() << " bytes). "
- << "Returned data located starting from block "
- << static_cast<uint64_t>(range_offset) + range_start
- << " (" << (static_cast<uint64_t>(range_offset) + range_start)
- * m_model.get_block_size() << " bytes) "
- << "and spanning a range of " << range_length << " blocks "
- << "(" << range_length * m_model.get_block_size() << " bytes)."
+ dout(0) << fmt::format("Data (Seed) Mismatch detected from block {}"
+ " ({} bytes) and spanning a range of {} blocks ({} bytes). "
+ "Returned data located starting from block {} ({} bytes) "
+ "and spanning a range of {} blocks ({} bytes).",
+ range_start,
+ range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ static_cast<uint64_t>(*range_offset) + range_start,
+ (static_cast<uint64_t>(*range_offset) + range_start)
+ * m_model.get_block_size(),
+ range_length,
+ range_length * m_model.get_block_size())
+ << dendl;
+ }
+ else
+ {
+ dout(0) << fmt::format("Data (Seed) Mismatch detected from block {}"
+ " ({} bytes) and spanning a range of {} blocks ({} bytes). "
+ "Data seed mismatch spanning a range of {} blocks ({} bytes).",
+ range_start,
+ range_start * m_model.get_block_size(),
+ range_length, range_length * m_model.get_block_size(),
+ range_length,
+ range_length * m_model.get_block_size())
<< dendl;
}
range_length = 1;
range_start = i;
- range_offset = seed_found_offsets.front() - i;
+ if (seed_found_offsets.size() > 0)
+ {
+ range_offset = seed_found_offsets.front() - i;
+ }
+ else
+ {
+ range_offset = std::nullopt;
+ }
}
}
start_block_offset + range_length_in_blocks - 1,
bufferlist);
}
- else if (range_length > 1)
+ 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) << "Data (Seed) Mismatch detected from block " << range_start
- << " (" << range_start * m_model.get_block_size() << " bytes) "
- << "and spanning a range of " << range_length << " blocks "
- << "(" << range_length * m_model.get_block_size() << " bytes). "
- << "Returned data located starting from block "
- << range_offset + range_start
- << " (" << (range_offset + range_start) * m_model.get_block_size()
- << " bytes) and spanning a range of " << range_length << " blocks "
- << "(" << range_length * m_model.get_block_size() << " bytes)."
+ 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;
}
}
uint64_t range_length_in_blocks,
const bufferlist& bufferlist)
{
- dout(0) << "Data Mismatch detected in blocks "
- << "from " << start_block_offset
- << " to " << start_block_offset + range_length_in_blocks - 1 << ". "
- << "Headers look as expected for range, "
- << "but generated data body does not match. "
- << "More information given for individual blocks below." << dendl;
+ 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++)
uint64_t range_length_in_blocks,
const bufferlist& bufferlist)
{
- dout(0) << "Data Mismatch detected in blocks "
- << "from " << start_block_offset
- << " to " << start_block_offset + range_length_in_blocks - 1 << ". "
- << "Headers look as expected for range, but generated data body does not match."
- << " More information given for individual blocks below." << dendl;
+ 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++)
uint64_t range_length_in_blocks,
const bufferlist& bufferlist)
{
- dout(0) << "Data not found for blocks "
- << "from " << start_block_offset
- << " to " << start_block_offset + range_length_in_blocks - 1 << ". "
- << "More information given for individual blocks below." << dendl;
+ 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++)
{