Skip to content

Commit b213047

Browse files
committed
DiskIO (macOS): add support
1 parent 085d092 commit b213047

File tree

3 files changed

+69
-20
lines changed

3 files changed

+69
-20
lines changed
Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,70 @@
11
#include "diskio.h"
2+
#include "util/apple/cf_helpers.h"
23

34
#include <IOKit/IOKitLib.h>
5+
#include <IOKit/IOBSD.h>
46
#include <IOKit/storage/IOMedia.h>
57
#include <IOKit/storage/IOBlockStorageDriver.h>
8+
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
9+
10+
static inline void wrapIoObjectRelease(io_service_t* service)
11+
{
12+
assert(service);
13+
if (*service)
14+
IOObjectRelease(*service);
15+
}
16+
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
617

718
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
819
{
9-
io_iterator_t iterator;
10-
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != kIOReturnSuccess)
20+
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
21+
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
1122
return "IOServiceGetMatchingServices() failed";
1223

1324
io_registry_entry_t registryEntry;
1425
while((registryEntry = IOIteratorNext(iterator)) != 0)
1526
{
16-
CFMutableDictionaryRef properties;
17-
if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess)
18-
{
19-
IOObjectRelease(registryEntry);
27+
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
28+
29+
io_name_t deviceName;
30+
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
2031
continue;
21-
}
2232

23-
io_registry_entry_t parent;
24-
IORegistryEntryGetParentEntry(registryEntry, kIOServicePlane, &parent);
25-
if(IOObjectConformsTo(parent, kIOBlockStorageDriverClass)) continue;
33+
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
34+
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
35+
continue;
2636

27-
io_name_t name;
28-
if (IORegistryEntryGetName(registryEntry, name) != KERN_SUCCESS)
37+
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
2938
continue;
3039

31-
// NSDictionary* props = (__bridge NSDictionary*) properties;
40+
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions);
41+
if (!statistics)
42+
continue;
3243

33-
// id statistics = [props valueForKey:@(kIOBlockStorageDriverStatisticsKey)];
34-
// if (!statistics) continue;
44+
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
45+
ffStrbufInitS(&device->name, deviceName);
46+
ffStrbufInit(&device->devPath);
47+
ffStrbufInit(&device->type);
48+
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
49+
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
50+
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount);
51+
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount);
3552

36-
// id volGroupaMntFromName = [props valueForKey:@"VolGroupMntFromName"];
37-
// if (!volGroupaMntFromName) continue;
53+
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
54+
if (bsdName)
55+
{
56+
ffCfStrGetString(bsdName, &device->devPath);
57+
ffStrbufPrependS(&device->devPath, "/dev/");
58+
}
3859

39-
// NSLog(@"%@", props);
60+
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
61+
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
62+
{
63+
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
64+
if (protocolCharacteristics)
65+
ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->type);
66+
}
4067
}
4168

42-
IOObjectRelease(iterator);
43-
4469
return NULL;
4570
}

src/util/apple/cf_helpers.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,29 @@ const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result)
8383
return "TypeID is neither 'CFNumber' nor 'CFData'";
8484
}
8585

86+
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result)
87+
{
88+
CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);
89+
if(cf == NULL)
90+
return "CFDictionaryGetValue() failed";
91+
92+
if(CFGetTypeID(cf) == CFNumberGetTypeID())
93+
{
94+
if(!CFNumberGetValue((CFNumberRef)cf, kCFNumberSInt64Type, result))
95+
return "Number type is not SInt64";
96+
return NULL;
97+
}
98+
else if(CFGetTypeID(cf) == CFDataGetTypeID())
99+
{
100+
if(CFDataGetLength((CFDataRef)cf) != sizeof(int64_t))
101+
return "Data length is not sizeof(int64_t)";
102+
CFDataGetBytes((CFDataRef)cf, CFRangeMake(0, sizeof(int64_t)), (uint8_t*)result);
103+
return NULL;
104+
}
105+
106+
return "TypeID is neither 'CFNumber' nor 'CFData'";
107+
}
108+
86109
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length)
87110
{
88111
CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key);

src/util/apple/cf_helpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const char* ffCfStrGetString(CFStringRef str, FFstrbuf* result);
1111
const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result);
1212
const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result);
1313
const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result);
14+
const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result);
1415
const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length);
1516
const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result);
1617

0 commit comments

Comments
 (0)