ohmu
·
2026-10-15
1#include "diskio.h"
2#include "common/debug.h"
3#include "common/apple/cf_helpers.h"
4
5#include <IOKit/IOKitLib.h>
6#include <IOKit/IOBSD.h>
7#include <IOKit/storage/IOMedia.h>
8#include <IOKit/storage/IOBlockStorageDriver.h>
9#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
10#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
11
12const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) {
13 FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
14 if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOBlockStorageDriverClass), &iterator) != KERN_SUCCESS) {
15 FF_DEBUG("IOServiceGetMatchingServices() failed");
16 return "IOServiceGetMatchingServices() failed";
17 }
18
19 io_registry_entry_t registryEntry;
20 while ((registryEntry = IOIteratorNext(iterator)) != IO_OBJECT_NULL) {
21 FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = registryEntry;
22
23 FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryMedia = IO_OBJECT_NULL;
24 if (IORegistryEntryGetChildEntry(entryDriver, kIOServicePlane, &entryMedia) != KERN_SUCCESS) {
25 continue;
26 }
27
28 io_name_t deviceName;
29 if (IORegistryEntryGetName(entryMedia, deviceName) != KERN_SUCCESS) {
30 continue;
31 }
32
33 if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0) {
34 continue;
35 }
36
37 FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions);
38 if (!statistics) {
39 continue;
40 }
41
42 FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result);
43 ffStrbufInitS(&device->name, deviceName);
44 ffStrbufInit(&device->devPath);
45
46 ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
47 ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
48 ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount);
49 ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount);
50
51 FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryMedia, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
52 if (bsdName) {
53 ffCfStrGetString(bsdName, &device->devPath);
54 ffStrbufPrependS(&device->devPath, "/dev/");
55 }
56 }
57
58 return nullptr;
59}