diff options
| author | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
|---|---|---|
| committer | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
| commit | 76424950e373d3b04ac3dd13019151bfba3e8423 (patch) | |
| tree | 4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/diskio/diskio.c | |
Add the files
Diffstat (limited to 'src/detection/diskio/diskio.c')
| -rw-r--r-- | src/detection/diskio/diskio.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/detection/diskio/diskio.c b/src/detection/diskio/diskio.c new file mode 100644 index 0000000..6ff66be --- /dev/null +++ b/src/detection/diskio/diskio.c @@ -0,0 +1,88 @@ +#include "diskio.h" + +#include "common/time.h" + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options); + +static FFlist ioCounters1; +static uint64_t time1; + +void ffPrepareDiskIO(FFDiskIOOptions* options) { + if (options->detectTotal) { + return; + } + + if (time1 != 0) { + return; // Already prepared + } + + ffListInit(&ioCounters1); + ffDiskIOGetIoCounters(&ioCounters1, options); + time1 = ffTimeGetNow(); +} + +const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options) { + const char* error = NULL; + + if (options->detectTotal) { + error = ffDiskIOGetIoCounters(result, options); + if (error) { + return error; + } + return NULL; + } + + if (time1 == 0) { + ffListInit(&ioCounters1); + error = ffDiskIOGetIoCounters(&ioCounters1, options); + if (error) { + return error; + } + time1 = ffTimeGetNow(); + } + + if (ioCounters1.length == 0) { + return "No physical disk found"; + } + + uint64_t time2 = ffTimeGetNow(); + while (time2 - time1 < options->waitTime) { + ffTimeSleep((uint32_t) (options->waitTime - (time2 - time1))); + time2 = ffTimeGetNow(); + } + + error = ffDiskIOGetIoCounters(result, options); + if (error) { + return error; + } + + if (result->length != ioCounters1.length) { + return "Different number of physical disks. Hardware change?"; + } + + for (uint32_t i = 0; i < result->length; ++i) { + FFDiskIOResult* icPrev = FF_LIST_GET(FFDiskIOResult, ioCounters1, i); + FFDiskIOResult* icCurr = FF_LIST_GET(FFDiskIOResult, *result, i); + if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath)) { + return "Physical disk device path changed"; + } + + static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout"); + for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t)) { + uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off); + uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off); + uint64_t temp = *currValue; + *currValue -= *prevValue; + *currValue /= (time2 - time1) / 1000 /* seconds */; + + // For next function call + *prevValue = temp; + } + } + + // For next function call + time1 = time2; + // Leak ioCounters1 here + + return NULL; +} |