Skip to content
API Documentation
BastionGuard™
FaultTolerantReader Class Reference

#include <fault_tolerant_reader.hpp>

Public Types

using CancelCallback = std::function<bool()>

Public Member Functions

 FaultTolerantReader ()=default
bool open (const std::string &path, std::string &error)
void close ()
bool is_open () const
uint64_t size () const
uint32_t logical_sector_size () const
const std::string & path () const
void set_config (const FaultTolerantReaderConfig &cfg)
void set_cancel_callback (CancelCallback cb)
ReadResult read_at (uint64_t offset, void *buffer, size_t size)
ReadResult read_rescue (uint64_t offset, void *buffer, size_t size)
const BadBlockMap & bad_block_map () const
BadBlockMap & bad_block_map ()

Private Member Functions

ReadResult read_rescue_recursive (uint64_t offset, unsigned char *buffer, size_t size)

Private Attributes

DiskReader reader_
FaultTolerantReaderConfig config_
CancelCallback cancel_cb_
BadBlockMap bad_map_
std::mutex mutex_

Detailed Description

Definition at line 27 of file fault_tolerant_reader.hpp.

Member Typedef Documentation

◆ CancelCallback

using FaultTolerantReader::CancelCallback = std::function<bool()>

Definition at line 29 of file fault_tolerant_reader.hpp.

Constructor & Destructor Documentation

◆ FaultTolerantReader()

Member Function Documentation

◆ bad_block_map() [1/2]

BadBlockMap & FaultTolerantReader::bad_block_map ( )

Definition at line 67 of file fault_tolerant_reader.cpp.

67 {
68 return bad_map_;
69}

References bad_map_.

◆ bad_block_map() [2/2]

const BadBlockMap & FaultTolerantReader::bad_block_map ( ) const

Definition at line 63 of file fault_tolerant_reader.cpp.

63 {
64 return bad_map_;
65}

References bad_map_.

Referenced by RescueImager::create_image(), and FaultTolerantReader().

◆ close()

void FaultTolerantReader::close ( )

Definition at line 11 of file fault_tolerant_reader.cpp.

11 {
12 std::scoped_lock lock(mutex_);
13 reader_.close();
14 bad_map_ = {};
15}

References bad_map_, DiskReader::close(), mutex_, and reader_.

Referenced by FaultTolerantReader().

◆ is_open()

bool FaultTolerantReader::is_open ( ) const

Definition at line 17 of file fault_tolerant_reader.cpp.

17 {
18 return reader_.is_open();
19}
bool is_open() const

References DiskReader::is_open(), and reader_.

Referenced by FaultTolerantReader().

◆ logical_sector_size()

uint32_t FaultTolerantReader::logical_sector_size ( ) const

Definition at line 25 of file fault_tolerant_reader.cpp.

25 {
27}
uint32_t logical_sector_size() const

References DiskReader::logical_sector_size(), and reader_.

Referenced by FaultTolerantReader().

◆ open()

bool FaultTolerantReader::open ( const std::string & path,
std::string & error )

Definition at line 7 of file fault_tolerant_reader.cpp.

7 {
8 return reader_.open_readonly(path, error);
9}
bool open_readonly(const std::string &path, std::string &error)
const std::string & path() const

References DiskReader::open_readonly(), path(), and reader_.

Referenced by RescueImager::create_image(), and FaultTolerantReader().

◆ path()

const std::string & FaultTolerantReader::path ( ) const

Definition at line 29 of file fault_tolerant_reader.cpp.

29 {
30 return reader_.path();
31}
const std::string & path() const

References DiskReader::path(), and reader_.

Referenced by FaultTolerantReader(), and open().

◆ read_at()

ReadResult FaultTolerantReader::read_at ( uint64_t offset,
void * buffer,
size_t size )

Definition at line 41 of file fault_tolerant_reader.cpp.

41 {
42 std::scoped_lock lock(mutex_);
43 ReadResult result;
44 if (cancel_cb_ && cancel_cb_()) {
45 result.error = "cancelled";
46 return result;
47 }
48 result.success = reader_.read_at(offset, buffer, size);
49 result.bytes_read = result.success ? size : 0;
50 if (result.success) {
52 } else {
53 result.error = "read failed";
54 }
55 return result;
56}
void mark_readable(uint64_t offset, uint64_t length)
bool read_at(uint64_t offset, void *buffer, size_t len)

References bad_map_, ReadResult::bytes_read, cancel_cb_, ReadResult::error, BadBlockMap::mark_readable(), mutex_, DiskReader::read_at(), reader_, size(), and ReadResult::success.

Referenced by FaultTolerantReader().

◆ read_rescue()

ReadResult FaultTolerantReader::read_rescue ( uint64_t offset,
void * buffer,
size_t size )

Definition at line 58 of file fault_tolerant_reader.cpp.

58 {
59 std::scoped_lock lock(mutex_);
60 return read_rescue_recursive(offset, static_cast<unsigned char*>(buffer), size);
61}
ReadResult read_rescue_recursive(uint64_t offset, unsigned char *buffer, size_t size)

References mutex_, read_rescue_recursive(), and size().

Referenced by RescueImager::create_image(), and FaultTolerantReader().

◆ read_rescue_recursive()

ReadResult FaultTolerantReader::read_rescue_recursive ( uint64_t offset,
unsigned char * buffer,
size_t size )
private

Definition at line 71 of file fault_tolerant_reader.cpp.

71 {
72 ReadResult result;
73 if (size == 0) {
74 result.success = true;
75 return result;
76 }
77 if (cancel_cb_ && cancel_cb_()) {
78 result.error = "cancelled";
79 return result;
80 }
81
82 const auto start = std::chrono::steady_clock::now();
83 for (int attempt = 0; attempt < std::max(1, config_.max_retries); ++attempt) {
84 if (reader_.read_at(offset, buffer, size)) {
85 result.success = true;
86 result.bytes_read = size;
88 const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
89 std::chrono::steady_clock::now() - start).count();
90 if (config_.mark_slow_ranges && elapsed > 250) {
91 bad_map_.mark_slow(offset, size);
92 }
93 return result;
94 }
95 std::this_thread::sleep_for(std::chrono::milliseconds(25 * (attempt + 1)));
96 }
97
99 bad_map_.mark_bad(offset, size);
100 result.error = "unreadable range";
101 return result;
102 }
103
104 const size_t left_size = size / 2;
105 const size_t right_size = size - left_size;
106 auto left = read_rescue_recursive(offset, buffer, left_size);
107 auto right = read_rescue_recursive(offset + left_size, buffer + left_size, right_size);
108
109 result.bytes_read = left.bytes_read + right.bytes_read;
110 result.partial = result.bytes_read > 0 && result.bytes_read < size;
111 result.success = (result.bytes_read == size);
112 if (!result.success && result.partial) {
113 result.error = "partial read";
114 } else if (!result.success) {
115 result.error = left.error.empty() ? right.error : left.error;
116 }
117 return result;
118}
void mark_slow(uint64_t offset, uint64_t length)
void mark_bad(uint64_t offset, uint64_t length)
FaultTolerantReaderConfig config_

References bad_map_, ReadResult::bytes_read, cancel_cb_, config_, ReadResult::error, BadBlockMap::mark_bad(), BadBlockMap::mark_readable(), BadBlockMap::mark_slow(), FaultTolerantReaderConfig::mark_slow_ranges, FaultTolerantReaderConfig::max_retries, FaultTolerantReaderConfig::min_chunk_size, ReadResult::partial, DiskReader::read_at(), read_rescue_recursive(), reader_, size(), and ReadResult::success.

Referenced by FaultTolerantReader(), read_rescue(), and read_rescue_recursive().

◆ set_cancel_callback()

void FaultTolerantReader::set_cancel_callback ( CancelCallback cb)

Definition at line 37 of file fault_tolerant_reader.cpp.

37 {
38 cancel_cb_ = std::move(cb);
39}

References cancel_cb_.

Referenced by RescueImager::create_image(), and FaultTolerantReader().

◆ set_config()

void FaultTolerantReader::set_config ( const FaultTolerantReaderConfig & cfg)

Definition at line 33 of file fault_tolerant_reader.cpp.

33 {
34 config_ = cfg;
35}

References config_.

Referenced by FaultTolerantReader().

◆ size()

uint64_t FaultTolerantReader::size ( ) const

Definition at line 21 of file fault_tolerant_reader.cpp.

21 {
22 return reader_.size();
23}
uint64_t size() const

References reader_, and DiskReader::size().

Referenced by RescueImager::create_image(), FaultTolerantReader(), read_at(), read_rescue(), and read_rescue_recursive().

Member Data Documentation

◆ bad_map_

BadBlockMap FaultTolerantReader::bad_map_
private

◆ cancel_cb_

CancelCallback FaultTolerantReader::cancel_cb_
private

Definition at line 55 of file fault_tolerant_reader.hpp.

Referenced by read_at(), read_rescue_recursive(), and set_cancel_callback().

◆ config_

FaultTolerantReaderConfig FaultTolerantReader::config_
private

Definition at line 54 of file fault_tolerant_reader.hpp.

Referenced by read_rescue_recursive(), and set_config().

◆ mutex_

std::mutex FaultTolerantReader::mutex_
mutableprivate

Definition at line 57 of file fault_tolerant_reader.hpp.

Referenced by close(), read_at(), and read_rescue().

◆ reader_

DiskReader FaultTolerantReader::reader_
private

The documentation for this class was generated from the following files: