+#if HAVE_IOKIT_IOKITLIB_H
+ io_registry_entry_t disk;
+ io_registry_entry_t disk_child;
+ io_iterator_t disk_list;
+ CFDictionaryRef props_dict;
+ CFDictionaryRef stats_dict;
+ CFDictionaryRef child_dict;
+ kern_return_t status;
+
+ signed long long read_ops;
+ signed long long read_byt;
+ signed long long read_tme;
+ signed long long write_ops;
+ signed long long write_byt;
+ signed long long write_tme;
+
+ int disk_major;
+ int disk_minor;
+ char disk_name[64];
+
+ static complain_t complain_obj;
+
+ /* Get the list of all disk objects. */
+ if (IOServiceGetMatchingServices (io_master_port,
+ IOServiceMatching (kIOBlockStorageDriverClass),
+ &disk_list) != kIOReturnSuccess)
+ {
+ plugin_complain (LOG_ERR, &complain_obj, "disk plugin: "
+ "IOServiceGetMatchingServices failed.");
+ return;
+ }
+ else if (complain_obj.interval != 0)
+ {
+ plugin_relief (LOG_NOTICE, &complain_obj, "disk plugin: "
+ "IOServiceGetMatchingServices succeeded.");
+ }
+
+ while ((disk = IOIteratorNext (disk_list)) != 0)
+ {
+ props_dict = NULL;
+ stats_dict = NULL;
+ child_dict = NULL;
+
+ /* `disk_child' must be released */
+ if ((status = IORegistryEntryGetChildEntry (disk, kIOServicePlane, &disk_child))
+ != kIOReturnSuccess)
+ {
+ /* This fails for example for DVD/CD drives.. */
+ DBG ("IORegistryEntryGetChildEntry (disk) failed: 0x%08x", status);
+ IOObjectRelease (disk);
+ continue;
+ }
+
+ /* We create `props_dict' => we need to release it later */
+ if (IORegistryEntryCreateCFProperties (disk,
+ (CFMutableDictionaryRef *) &props_dict,
+ kCFAllocatorDefault,
+ kNilOptions)
+ != kIOReturnSuccess)
+ {
+ syslog (LOG_ERR, "disk-plugin: IORegistryEntryCreateCFProperties failed.");
+ IOObjectRelease (disk_child);
+ IOObjectRelease (disk);
+ continue;
+ }
+
+ if (props_dict == NULL)
+ {
+ DBG ("IORegistryEntryCreateCFProperties (disk) failed.");
+ IOObjectRelease (disk_child);
+ IOObjectRelease (disk);
+ continue;
+ }
+
+ stats_dict = (CFDictionaryRef) CFDictionaryGetValue (props_dict,
+ CFSTR (kIOBlockStorageDriverStatisticsKey));
+
+ if (stats_dict == NULL)
+ {
+ DBG ("CFDictionaryGetValue (%s) failed.",
+ kIOBlockStorageDriverStatisticsKey);
+ CFRelease (props_dict);
+ IOObjectRelease (disk_child);
+ IOObjectRelease (disk);
+ continue;
+ }
+
+ if (IORegistryEntryCreateCFProperties (disk_child,
+ (CFMutableDictionaryRef *) &child_dict,
+ kCFAllocatorDefault,
+ kNilOptions)
+ != kIOReturnSuccess)
+ {
+ DBG ("IORegistryEntryCreateCFProperties (disk_child) failed.");
+ IOObjectRelease (disk_child);
+ CFRelease (props_dict);
+ IOObjectRelease (disk);
+ continue;
+ }
+
+ disk_major = (int) dict_get_value (child_dict,
+ kIOBSDMajorKey);
+ disk_minor = (int) dict_get_value (child_dict,
+ kIOBSDMinorKey);
+ read_ops = dict_get_value (stats_dict,
+ kIOBlockStorageDriverStatisticsReadsKey);
+ read_byt = dict_get_value (stats_dict,
+ kIOBlockStorageDriverStatisticsBytesReadKey);
+ read_tme = dict_get_value (stats_dict,
+ kIOBlockStorageDriverStatisticsTotalReadTimeKey);
+ write_ops = dict_get_value (stats_dict,
+ kIOBlockStorageDriverStatisticsWritesKey);
+ write_byt = dict_get_value (stats_dict,
+ kIOBlockStorageDriverStatisticsBytesWrittenKey);
+ write_tme = dict_get_value (stats_dict,
+ kIOBlockStorageDriverStatisticsTotalWriteTimeKey);
+
+ if (snprintf (disk_name, 64, "%i-%i", disk_major, disk_minor) >= 64)
+ {
+ DBG ("snprintf (major, minor) failed.");
+ CFRelease (child_dict);
+ IOObjectRelease (disk_child);
+ CFRelease (props_dict);
+ IOObjectRelease (disk);
+ continue;
+ }
+ DBG ("disk_name = %s", disk_name);
+
+ if ((read_ops != -1LL)
+ || (read_byt != -1LL)
+ || (read_tme != -1LL)
+ || (write_ops != -1LL)
+ || (write_byt != -1LL)
+ || (write_tme != -1LL))
+ disk_submit (disk_name,
+ read_ops, 0ULL, read_byt, read_tme,
+ write_ops, 0ULL, write_byt, write_tme);
+
+ CFRelease (child_dict);
+ IOObjectRelease (disk_child);
+ CFRelease (props_dict);
+ IOObjectRelease (disk);
+ }
+ IOObjectRelease (disk_list);
+/* #endif HAVE_IOKIT_IOKITLIB_H */
+
+#elif KERNEL_LINUX