Skip to content
API Documentation
BastionGuard™
DeviceHealthProbe Class Reference

#include <device_health_probe.hpp>

Public Types

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

Static Public Member Functions

static DeviceHealthReport probe (const std::string &device_path, CancelCallback cancel_cb={})

Detailed Description

Definition at line 40 of file device_health_probe.hpp.

Member Typedef Documentation

◆ CancelCallback

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

Definition at line 42 of file device_health_probe.hpp.

Member Function Documentation

◆ probe()

DeviceHealthReport DeviceHealthProbe::probe ( const std::string & device_path,
CancelCallback cancel_cb = {} )
static

Definition at line 38 of file device_health_probe.cpp.

38 {
39 DeviceHealthReport report;
40 report.device_path = device_path;
41
42 DiskReader reader;
43 std::string error;
44 report.open_ok = reader.open_readonly(device_path, error);
45 if (!report.open_ok) {
46 report.summary = "Device could not be opened: " + error;
48 return report;
49 }
50
51 report.total_size = reader.size();
53 report.size_suspicious = (report.total_size == 0 || report.total_size < 4096);
54
55 std::vector<uint64_t> offsets;
56 offsets.push_back(0);
57 if (report.total_size > (1ull << 20)) offsets.push_back(1ull << 20);
58 if (report.total_size > (16ull << 20)) offsets.push_back(16ull << 20);
59 if (report.total_size > 0) offsets.push_back(report.total_size / 2);
60 if (report.total_size > 4096) offsets.push_back(report.total_size - 4096);
61
62 size_t failures = 0;
63 size_t slow = 0;
64 for (const auto offset : offsets) {
65 if (cancel_cb && cancel_cb()) break;
66 auto sample = take_sample(reader, offset, 4096);
67 if (offset == 0) report.read_lba0_ok = sample.success;
68 if (offset + 4096 >= report.total_size) report.read_tail_ok = sample.success;
69 if (!sample.success) ++failures;
70 if (sample.latency_ms > 250) ++slow;
71 report.samples.push_back(std::move(sample));
72 }
73
74 report.unstable_latency = slow > 1;
75 report.intermittent_failures = failures > 0 && failures < report.samples.size();
76
77 if (failures == 0 && !report.size_suspicious && !report.unstable_latency) {
79 } else if (failures == 0 && report.unstable_latency) {
81 } else if (failures < report.samples.size() / 2 + 1) {
83 } else if (failures < report.samples.size()) {
85 } else {
87 }
88
89 report.summary = health_to_string(report.state);
90 if (report.size_suspicious) report.summary += "; suspicious size";
91 if (report.unstable_latency) report.summary += "; unstable latency";
92 if (report.intermittent_failures) report.summary += "; intermittent failures";
93
94 return report;
95}
uint32_t logical_sector_size() const
bool open_readonly(const std::string &path, std::string &error)
uint64_t size() const
std::string health_to_string(DeviceHealthState state)
DeviceProbeSample take_sample(DiskReader &reader, uint64_t offset, size_t size)
DeviceHealthState state
std::vector< DeviceProbeSample > samples

References DeviceHealthReport::device_path, EnumeratedButUnstable, Healthy, DeviceHealthReport::intermittent_failures, DeviceHealthReport::logical_sector_size, DiskReader::logical_sector_size(), NotReadable, DeviceHealthReport::open_ok, DiskReader::open_readonly(), PartiallyReadable, DeviceHealthReport::read_lba0_ok, DeviceHealthReport::read_tail_ok, ReadableWithErrors, DeviceHealthReport::samples, DiskReader::size(), DeviceHealthReport::size_suspicious, DeviceHealthReport::state, DeviceHealthReport::summary, DeviceHealthReport::total_size, and DeviceHealthReport::unstable_latency.

Referenced by DeviceEnumerator::enumerate_linux_block_devices(), and ScannerEngine::run_scan().


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