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_bsd.c | |
Add the files
Diffstat (limited to 'src/detection/diskio/diskio_bsd.c')
| -rw-r--r-- | src/detection/diskio/diskio_bsd.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c new file mode 100644 index 0000000..f5eb4b8 --- /dev/null +++ b/src/detection/diskio/diskio_bsd.c @@ -0,0 +1,120 @@ +#include "diskio.h" + +#if __has_include(<libgeom.h>) + + #include "common/strutil.h" + + #include <devstat.h> + #include <memory.h> + #include <fcntl.h> + #include <sys/ioctl.h> + #include <sys/disk.h> + #include <libgeom.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + FF_A_CLEANUP(geom_deletetree) struct gmesh geomTree = {}; + if (geom_gettree(&geomTree) < 0) { + return "geom_gettree() failed"; + } + + if (geom_stats_open() < 0) { + return "geom_stats_open() failed"; + } + + void* snap = geom_stats_snapshot_get(); + if (!snap) { + return "geom_stats_snapshot_get() failed"; + } + + struct devstat* snapIter; + while ((snapIter = geom_stats_snapshot_next(snap)) != NULL) { + if (snapIter->device_type & DEVSTAT_TYPE_PASS) { + continue; + } + struct gident* geomId = geom_lookupid(&geomTree, snapIter->id); + if (geomId == NULL) { + continue; + } + if (geomId->lg_what != ISPROVIDER) { + continue; + } + struct gprovider* provider = (struct gprovider*) geomId->lg_ptr; + if (provider->lg_geom->lg_rank != 1) { + continue; + } + + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next) { + if (ffStrEquals(ptr->lg_name, "descr")) { + ffStrbufSetS(&name, ptr->lg_val); + } + } + if (name.length == 0) { + ffStrbufSetS(&name, provider->lg_name); + } + + if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name); + device->bytesRead = snapIter->bytes[DEVSTAT_READ]; + device->readCount = snapIter->operations[DEVSTAT_READ]; + device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE]; + device->writeCount = snapIter->operations[DEVSTAT_WRITE]; + ffStrbufInitMove(&device->name, &name); + } + + geom_stats_snapshot_free(snap); + geom_stats_close(); + + return NULL; +} + +#else + + #include <devstat.h> + #include <memory.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + if (checkversion() < 0) { + return "checkversion() failed"; + } + + struct statinfo stats = { + .dinfo = (struct devinfo*) calloc(1, sizeof(struct devinfo)), + }; + if (getdevs(&stats) < 0) { + return "getdevs() failed"; + } + + for (int i = 0; i < stats.dinfo->numdevs; i++) { + struct devstat* current = &stats.dinfo->devices[i]; + if (current->device_type & DEVSTAT_TYPE_PASS) { + continue; + } + + char deviceName[128]; + snprintf(deviceName, sizeof(deviceName), "%s%d", current->device_name, current->unit_number); + + if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitS(&device->name, deviceName); + ffStrbufInitF(&device->devPath, "/dev/%s", deviceName); + device->bytesRead = current->bytes_read; + device->readCount = current->num_reads; + device->bytesWritten = current->bytes_written; + device->writeCount = current->num_writes; + } + + free(stats.dinfo->mem_ptr); + free(stats.dinfo); + + return NULL; +} + +#endif |