...

Text file src/github.com/shirou/gopsutil/disk/iostat_darwin.c

Documentation: github.com/shirou/gopsutil/disk

     1// https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.c
     2#include <stdint.h>
     3#include <CoreFoundation/CoreFoundation.h>
     4#include "iostat_darwin.h"
     5
     6#define IOKIT	1	/* to get io_name_t in device_types.h */
     7
     8#include <IOKit/IOKitLib.h>
     9#include <IOKit/storage/IOBlockStorageDriver.h>
    10#include <IOKit/storage/IOMedia.h>
    11#include <IOKit/IOBSD.h>
    12
    13#include <mach/mach_host.h>
    14
    15static int getdrivestat(io_registry_entry_t d, DriveStats *stat);
    16static int fillstat(io_registry_entry_t d, DriveStats *stat);
    17
    18int
    19readdrivestat(DriveStats a[], int n)
    20{
    21	mach_port_t port;
    22	CFMutableDictionaryRef match;
    23	io_iterator_t drives;
    24	io_registry_entry_t d;
    25	kern_return_t status;
    26	int na, rv;
    27
    28	IOMasterPort(bootstrap_port, &port);
    29	match = IOServiceMatching("IOMedia");
    30	CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
    31	status = IOServiceGetMatchingServices(port, match, &drives);
    32	if(status != KERN_SUCCESS)
    33		return -1;
    34
    35	na = 0;
    36	while(na < n && (d=IOIteratorNext(drives)) > 0){
    37		rv = getdrivestat(d, &a[na]);
    38		if(rv < 0)
    39			return -1;
    40		if(rv > 0)
    41			na++;
    42		IOObjectRelease(d);
    43	}
    44	IOObjectRelease(drives);
    45	return na;
    46}
    47
    48static int
    49getdrivestat(io_registry_entry_t d, DriveStats *stat)
    50{
    51	io_registry_entry_t parent;
    52	kern_return_t status;
    53	CFDictionaryRef props;
    54	CFStringRef name;
    55	CFNumberRef num;
    56	int rv;
    57
    58	memset(stat, 0, sizeof *stat);
    59	status = IORegistryEntryGetParentEntry(d, kIOServicePlane, &parent);
    60	if(status != KERN_SUCCESS)
    61		return -1;
    62	if(!IOObjectConformsTo(parent, "IOBlockStorageDriver")){
    63		IOObjectRelease(parent);
    64		return 0;
    65	}
    66
    67	status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions);
    68	if(status != KERN_SUCCESS){
    69		IOObjectRelease(parent);
    70		return -1;
    71	}
    72	name = (CFStringRef)CFDictionaryGetValue(props, CFSTR(kIOBSDNameKey));
    73	CFStringGetCString(name, stat->name, NAMELEN, CFStringGetSystemEncoding());
    74	num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaSizeKey));
    75	CFNumberGetValue(num, kCFNumberSInt64Type, &stat->size);
    76	num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaPreferredBlockSizeKey));
    77	CFNumberGetValue(num, kCFNumberSInt64Type, &stat->blocksize);
    78	CFRelease(props);
    79
    80	rv = fillstat(parent, stat);
    81	IOObjectRelease(parent);
    82	if(rv < 0)
    83		return -1;
    84	return 1;
    85}
    86
    87static struct {
    88	char *key;
    89	size_t off;
    90} statstab[] = {
    91	{kIOBlockStorageDriverStatisticsBytesReadKey, offsetof(DriveStats, read)},
    92	{kIOBlockStorageDriverStatisticsBytesWrittenKey, offsetof(DriveStats, written)},
    93	{kIOBlockStorageDriverStatisticsReadsKey, offsetof(DriveStats, nread)},
    94	{kIOBlockStorageDriverStatisticsWritesKey, offsetof(DriveStats, nwrite)},
    95	{kIOBlockStorageDriverStatisticsTotalReadTimeKey, offsetof(DriveStats, readtime)},
    96	{kIOBlockStorageDriverStatisticsTotalWriteTimeKey, offsetof(DriveStats, writetime)},
    97	{kIOBlockStorageDriverStatisticsLatentReadTimeKey, offsetof(DriveStats, readlat)},
    98	{kIOBlockStorageDriverStatisticsLatentWriteTimeKey, offsetof(DriveStats, writelat)},
    99};
   100
   101static int
   102fillstat(io_registry_entry_t d, DriveStats *stat)
   103{
   104	CFDictionaryRef props, v;
   105	CFNumberRef num;
   106	kern_return_t status;
   107	typeof(statstab[0]) *bp, *ep;
   108
   109	status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions);
   110	if(status != KERN_SUCCESS)
   111		return -1;
   112	v = (CFDictionaryRef)CFDictionaryGetValue(props, CFSTR(kIOBlockStorageDriverStatisticsKey));
   113	if(v == NULL){
   114		CFRelease(props);
   115		return -1;
   116	}
   117
   118	ep = &statstab[sizeof(statstab)/sizeof(statstab[0])];
   119	for(bp = &statstab[0]; bp < ep; bp++){
   120		CFStringRef s;
   121
   122		s = CFStringCreateWithCString(kCFAllocatorDefault, bp->key, CFStringGetSystemEncoding());
   123		num = (CFNumberRef)CFDictionaryGetValue(v, s);
   124		if(num)
   125			CFNumberGetValue(num, kCFNumberSInt64Type, ((char*)stat)+bp->off);
   126		CFRelease(s);
   127	}
   128
   129	CFRelease(props);
   130	return 0;
   131}

View as plain text