add diskstats on Darwin (#593)
* Add diskstats collector for Darwin * Update year in the header * Update README.md * Add github.com/lufia/iostat to vendored packages * Change stats to follow naming guidelines * Add a entry of github.com/lufia/iostat into vendor.json * Remove /proc/diskstats from description
This commit is contained in:
parent
ab3414e6fd
commit
a077024f51
10 changed files with 440 additions and 1 deletions
128
vendor/github.com/lufia/iostat/iostat_darwin.c
generated
vendored
Normal file
128
vendor/github.com/lufia/iostat/iostat_darwin.c
generated
vendored
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#include <stdint.h>
|
||||
#include "iostat_darwin.h"
|
||||
|
||||
#define IOKIT 1 /* to get io_name_t in device_types.h */
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/storage/IOBlockStorageDriver.h>
|
||||
#include <IOKit/storage/IOMedia.h>
|
||||
#include <IOKit/IOBSD.h>
|
||||
|
||||
static int getdrivestat(io_registry_entry_t d, DriveStats *stat);
|
||||
static int fillstat(io_registry_entry_t d, DriveStats *stat);
|
||||
|
||||
int
|
||||
readdrivestat(DriveStats a[], int n)
|
||||
{
|
||||
mach_port_t port;
|
||||
CFMutableDictionaryRef match;
|
||||
io_iterator_t drives;
|
||||
io_registry_entry_t d;
|
||||
kern_return_t status;
|
||||
int na, rv;
|
||||
|
||||
IOMasterPort(bootstrap_port, &port);
|
||||
match = IOServiceMatching("IOMedia");
|
||||
CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
|
||||
status = IOServiceGetMatchingServices(port, match, &drives);
|
||||
if(status != KERN_SUCCESS)
|
||||
return -1;
|
||||
|
||||
na = 0;
|
||||
while(na < n && (d=IOIteratorNext(drives)) > 0){
|
||||
rv = getdrivestat(d, &a[na]);
|
||||
if(rv < 0)
|
||||
return -1;
|
||||
if(rv > 0)
|
||||
na++;
|
||||
IOObjectRelease(d);
|
||||
}
|
||||
IOObjectRelease(drives);
|
||||
return na;
|
||||
}
|
||||
|
||||
static int
|
||||
getdrivestat(io_registry_entry_t d, DriveStats *stat)
|
||||
{
|
||||
io_registry_entry_t parent;
|
||||
kern_return_t status;
|
||||
CFDictionaryRef props;
|
||||
CFStringRef name;
|
||||
CFNumberRef num;
|
||||
int rv;
|
||||
|
||||
memset(stat, 0, sizeof *stat);
|
||||
status = IORegistryEntryGetParentEntry(d, kIOServicePlane, &parent);
|
||||
if(status != KERN_SUCCESS)
|
||||
return -1;
|
||||
if(!IOObjectConformsTo(parent, "IOBlockStorageDriver")){
|
||||
IOObjectRelease(parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions);
|
||||
if(status != KERN_SUCCESS){
|
||||
IOObjectRelease(parent);
|
||||
return -1;
|
||||
}
|
||||
name = (CFStringRef)CFDictionaryGetValue(props, CFSTR(kIOBSDNameKey));
|
||||
CFStringGetCString(name, stat->name, NAMELEN, CFStringGetSystemEncoding());
|
||||
num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaSizeKey));
|
||||
CFNumberGetValue(num, kCFNumberSInt64Type, &stat->size);
|
||||
num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaPreferredBlockSizeKey));
|
||||
CFNumberGetValue(num, kCFNumberSInt64Type, &stat->blocksize);
|
||||
CFRelease(props);
|
||||
|
||||
rv = fillstat(parent, stat);
|
||||
IOObjectRelease(parent);
|
||||
if(rv < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct {
|
||||
char *key;
|
||||
size_t off;
|
||||
} statstab[] = {
|
||||
{kIOBlockStorageDriverStatisticsBytesReadKey, offsetof(DriveStats, read)},
|
||||
{kIOBlockStorageDriverStatisticsBytesWrittenKey, offsetof(DriveStats, written)},
|
||||
{kIOBlockStorageDriverStatisticsReadsKey, offsetof(DriveStats, nread)},
|
||||
{kIOBlockStorageDriverStatisticsWritesKey, offsetof(DriveStats, nwrite)},
|
||||
{kIOBlockStorageDriverStatisticsTotalReadTimeKey, offsetof(DriveStats, readtime)},
|
||||
{kIOBlockStorageDriverStatisticsTotalWriteTimeKey, offsetof(DriveStats, writetime)},
|
||||
{kIOBlockStorageDriverStatisticsLatentReadTimeKey, offsetof(DriveStats, readlat)},
|
||||
{kIOBlockStorageDriverStatisticsLatentWriteTimeKey, offsetof(DriveStats, writelat)},
|
||||
};
|
||||
|
||||
static int
|
||||
fillstat(io_registry_entry_t d, DriveStats *stat)
|
||||
{
|
||||
CFDictionaryRef props, v;
|
||||
CFNumberRef num;
|
||||
kern_return_t status;
|
||||
typeof(statstab[0]) *bp, *ep;
|
||||
|
||||
status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions);
|
||||
if(status != KERN_SUCCESS)
|
||||
return -1;
|
||||
v = (CFDictionaryRef)CFDictionaryGetValue(props, CFSTR(kIOBlockStorageDriverStatisticsKey));
|
||||
if(v == NULL){
|
||||
CFRelease(props);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ep = &statstab[sizeof(statstab)/sizeof(statstab[0])];
|
||||
for(bp = &statstab[0]; bp < ep; bp++){
|
||||
CFStringRef s;
|
||||
|
||||
s = CFStringCreateWithCString(kCFAllocatorDefault, bp->key, CFStringGetSystemEncoding());
|
||||
num = (CFNumberRef)CFDictionaryGetValue(v, s);
|
||||
if(num)
|
||||
CFNumberGetValue(num, kCFNumberSInt64Type, ((char*)stat)+bp->off);
|
||||
CFRelease(s);
|
||||
}
|
||||
|
||||
CFRelease(props);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue