Fix integer sizing issues in the DiskIO Meter

On Linux kernels the size of the values exported for block
device bytes has used a 64 bit integer for quite some time
(2.6+ IIRC).  Make the procfs value extraction use correct
types and change internal types used to rate convert these
counters (within the DiskIO Meter) 64 bit integers, where
appropriate.
This commit is contained in:
Nathan Scott 2021-03-01 12:10:18 +11:00
parent 379421d3b2
commit 00339087b0
4 changed files with 25 additions and 19 deletions

View File

@ -26,12 +26,12 @@ static const int DiskIOMeter_attributes[] = {
}; };
static bool hasData = false; static bool hasData = false;
static unsigned long int cached_read_diff = 0; static unsigned long int cached_read_diff;
static unsigned long int cached_write_diff = 0; static unsigned long int cached_write_diff;
static double cached_utilisation_diff = 0.0; static double cached_utilisation_diff;
static void DiskIOMeter_updateValues(Meter* this, char* buffer, size_t len) { static void DiskIOMeter_updateValues(Meter* this, char* buffer, size_t len) {
static unsigned long long int cached_last_update = 0; static unsigned long long int cached_last_update;
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
@ -40,9 +40,10 @@ static void DiskIOMeter_updateValues(Meter* this, char* buffer, size_t len) {
/* update only every 500ms */ /* update only every 500ms */
if (passedTimeInMs > 500) { if (passedTimeInMs > 500) {
static unsigned long int cached_read_total = 0; static unsigned long long int cached_read_total;
static unsigned long int cached_write_total = 0; static unsigned long long int cached_write_total;
static unsigned long int cached_msTimeSpend_total = 0; static unsigned long long int cached_msTimeSpend_total;
unsigned long long int diff;
cached_last_update = timeInMilliSeconds; cached_last_update = timeInMilliSeconds;
@ -56,21 +57,26 @@ static void DiskIOMeter_updateValues(Meter* this, char* buffer, size_t len) {
} }
if (data.totalBytesRead > cached_read_total) { if (data.totalBytesRead > cached_read_total) {
cached_read_diff = (data.totalBytesRead - cached_read_total) / 1024; /* Meter_humanUnit() expects unit in kilo */ diff = data.totalBytesRead - cached_read_total;
diff /= 1024; /* Meter_humanUnit() expects unit in kilo */
cached_read_diff = (unsigned int)diff;
} else { } else {
cached_read_diff = 0; cached_read_diff = 0UL;
} }
cached_read_total = data.totalBytesRead; cached_read_total = data.totalBytesRead;
if (data.totalBytesWritten > cached_write_total) { if (data.totalBytesWritten > cached_write_total) {
cached_write_diff = (data.totalBytesWritten - cached_write_total) / 1024; /* Meter_humanUnit() expects unit in kilo */ diff = data.totalBytesWritten - cached_write_total;
diff /= 1024; /* Meter_humanUnit() expects unit in kilo */
cached_write_diff = (unsigned int)diff;
} else { } else {
cached_write_diff = 0; cached_write_diff = 0UL;
} }
cached_write_total = data.totalBytesWritten; cached_write_total = data.totalBytesWritten;
if (data.totalMsTimeSpend > cached_msTimeSpend_total) { if (data.totalMsTimeSpend > cached_msTimeSpend_total) {
cached_utilisation_diff = 100 * (double)(data.totalMsTimeSpend - cached_msTimeSpend_total) / passedTimeInMs; diff = data.totalMsTimeSpend - cached_msTimeSpend_total;
cached_utilisation_diff = 100.0 * (double)diff / passedTimeInMs;
} else { } else {
cached_utilisation_diff = 0.0; cached_utilisation_diff = 0.0;
} }

View File

@ -10,9 +10,9 @@ in the source distribution for its full text.
#include "Meter.h" #include "Meter.h"
typedef struct DiskIOData_ { typedef struct DiskIOData_ {
unsigned long int totalBytesRead; unsigned long long int totalBytesRead;
unsigned long int totalBytesWritten; unsigned long long int totalBytesWritten;
unsigned long int totalMsTimeSpend; unsigned long long int totalMsTimeSpend;
} DiskIOData; } DiskIOData;
extern const MeterClass DiskIOMeter_class; extern const MeterClass DiskIOMeter_class;

View File

@ -289,7 +289,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
int count = current.dinfo->numdevs; int count = current.dinfo->numdevs;
unsigned long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0; unsigned long long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0;
// get data // get data
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {

View File

@ -494,12 +494,12 @@ bool Platform_getDiskIO(DiskIOData* data) {
if (!fd) if (!fd)
return false; return false;
unsigned long int read_sum = 0, write_sum = 0, timeSpend_sum = 0; unsigned long long int read_sum = 0, write_sum = 0, timeSpend_sum = 0;
char lineBuffer[256]; char lineBuffer[256];
while (fgets(lineBuffer, sizeof(lineBuffer), fd)) { while (fgets(lineBuffer, sizeof(lineBuffer), fd)) {
char diskname[32]; char diskname[32];
unsigned long int read_tmp, write_tmp, timeSpend_tmp; unsigned long long int read_tmp, write_tmp, timeSpend_tmp;
if (sscanf(lineBuffer, "%*d %*d %31s %*u %*u %lu %*u %*u %*u %lu %*u %*u %lu", diskname, &read_tmp, &write_tmp, &timeSpend_tmp) == 4) { if (sscanf(lineBuffer, "%*d %*d %31s %*u %*u %llu %*u %*u %*u %llu %*u %*u %llu", diskname, &read_tmp, &write_tmp, &timeSpend_tmp) == 4) {
if (String_startsWith(diskname, "dm-")) if (String_startsWith(diskname, "dm-"))
continue; continue;