ohmu
·
2026-10-15
1#include "diskio.h"
2#include "common/debug.h"
3#include "common/strutil.h"
4#include <kstat.h>
5
6static inline void kstatFreeWrap(kstat_ctl_t** pkc) {
7 assert(pkc);
8 if (*pkc) {
9 kstat_close(*pkc);
10 }
11}
12
13const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) {
14 [[gnu::cleanup(kstatFreeWrap)]] kstat_ctl_t* kc = kstat_open();
15 if (!kc) {
16 FF_DEBUG("kstat_open() failed");
17 return "kstat_open() failed";
18 }
19
20 for (kstat_t* ks = kc->kc_chain; ks; ks = ks->ks_next) {
21 if (ks->ks_type != KSTAT_TYPE_IO || !ffStrEquals(ks->ks_class, "disk")) {
22 continue;
23 }
24
25 if (options->namePrefix.length && strncmp(ks->ks_name, options->namePrefix.chars, options->namePrefix.length) != 0) {
26 continue;
27 }
28
29 kstat_io_t kio;
30 if (kstat_read(kc, ks, &kio) < 0) {
31 continue;
32 }
33
34 FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result);
35 ffStrbufInit(&device->devPath); // unlike other platforms, `/dev/ks_name` is not available
36 ffStrbufInitS(&device->name, ks->ks_name);
37 device->bytesRead = kio.nread;
38 device->readCount = kio.reads;
39 device->bytesWritten = kio.nwritten;
40 device->writeCount = kio.writes;
41 }
42
43 return nullptr;
44}