summaryrefslogtreecommitdiffstats
path: root/src/detection/diskio/diskio_bsd.c
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /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.c120
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