check if at least one object was read before updating ZFS pool io in zfs_collect_pool_total_stats(), use try-catch to prevent possible crashes from int_64t conversions

This commit is contained in:
simplepad 2022-07-09 03:46:15 +03:00
parent 4969dd8dc6
commit 189cba73e4
No known key found for this signature in database
GPG Key ID: 00DB76DD9FB623EC
1 changed files with 29 additions and 19 deletions

View File

@ -1182,34 +1182,41 @@ namespace Mem {
bool zfs_collect_pool_total_stats(struct disk_info &disk) { bool zfs_collect_pool_total_stats(struct disk_info &disk) {
ifstream diskread; ifstream diskread;
int64_t bytes_read, bytes_write, io_ticks, bytes_read_total = 0, bytes_write_total = 0, io_ticks_total = 0; int64_t bytes_read, bytes_write, io_ticks, bytes_read_total = 0, bytes_write_total = 0, io_ticks_total = 0, objects_read = 0;
// looking through all files that start with 'objset' // looking through all files that start with 'objset'
for (const auto& file: fs::directory_iterator(disk.stat)) { for (const auto& file: fs::directory_iterator(disk.stat)) {
if ((file.path().filename()).string().starts_with("objset")) { if ((file.path().filename()).string().starts_with("objset")) {
diskread.open(file.path()); diskread.open(file.path());
if (diskread.good()) { if (diskread.good()) {
// skip first three lines try {
for (int i = 0; i < 3; i++) diskread.ignore(numeric_limits<streamsize>::max(), '\n'); // skip first three lines
// skip characters until '4' is reached, indicating data type 4, next value will be out target for (int i = 0; i < 3; i++) diskread.ignore(numeric_limits<streamsize>::max(), '\n');
diskread.ignore(numeric_limits<streamsize>::max(), '4'); // skip characters until '4' is reached, indicating data type 4, next value will be out target
diskread >> io_ticks; diskread.ignore(numeric_limits<streamsize>::max(), '4');
io_ticks_total += io_ticks; diskread >> io_ticks;
io_ticks_total += io_ticks;
// skip characters until '4' is reached, indicating data type 4, next value will be out target // skip characters until '4' is reached, indicating data type 4, next value will be out target
diskread.ignore(numeric_limits<streamsize>::max(), '4'); diskread.ignore(numeric_limits<streamsize>::max(), '4');
diskread >> bytes_write; diskread >> bytes_write;
bytes_write_total += bytes_write; bytes_write_total += bytes_write;
// skip characters until '4' is reached, indicating data type 4, next value will be out target // skip characters until '4' is reached, indicating data type 4, next value will be out target
diskread.ignore(numeric_limits<streamsize>::max(), '4'); diskread.ignore(numeric_limits<streamsize>::max(), '4');
diskread >> io_ticks; diskread >> io_ticks;
io_ticks_total += io_ticks; io_ticks_total += io_ticks;
// skip characters until '4' is reached, indicating data type 4, next value will be out target // skip characters until '4' is reached, indicating data type 4, next value will be out target
diskread.ignore(numeric_limits<streamsize>::max(), '4'); diskread.ignore(numeric_limits<streamsize>::max(), '4');
diskread >> bytes_read; diskread >> bytes_read;
bytes_read_total += bytes_read; bytes_read_total += bytes_read;
} catch (const std::exception& e) {
continue;
}
// increment read objects counter if no errors were encountered
objects_read++;
} else { } else {
Logger::warning("Could not read file: " + file.path().string()); Logger::warning("Could not read file: " + file.path().string());
} }
@ -1217,6 +1224,9 @@ namespace Mem {
} }
} }
// if for some reason no objects were read
if (objects_read == 0) return false;
if (disk.io_write.empty()) if (disk.io_write.empty())
disk.io_write.push_back(0); disk.io_write.push_back(0);
else else