From 00339087b0ec7ab951eb65b03a2d1d66d97517f0 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Mon, 1 Mar 2021 12:10:18 +1100 Subject: 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. --- DiskIOMeter.c | 30 ++++++++++++++++++------------ DiskIOMeter.h | 6 +++--- freebsd/Platform.c | 2 +- linux/Platform.c | 6 +++--- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/DiskIOMeter.c b/DiskIOMeter.c index 52b14611..1c0c2ba4 100644 --- a/DiskIOMeter.c +++ b/DiskIOMeter.c @@ -26,12 +26,12 @@ static const int DiskIOMeter_attributes[] = { }; static bool hasData = false; -static unsigned long int cached_read_diff = 0; -static unsigned long int cached_write_diff = 0; -static double cached_utilisation_diff = 0.0; +static unsigned long int cached_read_diff; +static unsigned long int cached_write_diff; +static double cached_utilisation_diff; 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; gettimeofday(&tv, NULL); @@ -40,9 +40,10 @@ static void DiskIOMeter_updateValues(Meter* this, char* buffer, size_t len) { /* update only every 500ms */ if (passedTimeInMs > 500) { - static unsigned long int cached_read_total = 0; - static unsigned long int cached_write_total = 0; - static unsigned long int cached_msTimeSpend_total = 0; + static unsigned long long int cached_read_total; + static unsigned long long int cached_write_total; + static unsigned long long int cached_msTimeSpend_total; + unsigned long long int diff; 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) { - 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 { - cached_read_diff = 0; + cached_read_diff = 0UL; } cached_read_total = data.totalBytesRead; 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 { - cached_write_diff = 0; + cached_write_diff = 0UL; } cached_write_total = data.totalBytesWritten; 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 { cached_utilisation_diff = 0.0; } diff --git a/DiskIOMeter.h b/DiskIOMeter.h index b2b3e8dd..8b31dfa3 100644 --- a/DiskIOMeter.h +++ b/DiskIOMeter.h @@ -10,9 +10,9 @@ in the source distribution for its full text. #include "Meter.h" typedef struct DiskIOData_ { - unsigned long int totalBytesRead; - unsigned long int totalBytesWritten; - unsigned long int totalMsTimeSpend; + unsigned long long int totalBytesRead; + unsigned long long int totalBytesWritten; + unsigned long long int totalMsTimeSpend; } DiskIOData; extern const MeterClass DiskIOMeter_class; diff --git a/freebsd/Platform.c b/freebsd/Platform.c index 9f8c051f..19a6f94f 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -289,7 +289,7 @@ bool Platform_getDiskIO(DiskIOData* data) { 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 for (int i = 0; i < count; i++) { diff --git a/linux/Platform.c b/linux/Platform.c index da2ae606..662a62ce 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -494,12 +494,12 @@ bool Platform_getDiskIO(DiskIOData* data) { if (!fd) 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]; while (fgets(lineBuffer, sizeof(lineBuffer), fd)) { char diskname[32]; - unsigned 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) { + unsigned long long int read_tmp, write_tmp, timeSpend_tmp; + 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-")) continue; -- cgit v1.2.3