X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdisk.c;h=c809fdb6a33c0762b6b002a6a66367e1a884660c;hb=70a5b80271643b3c0384e03a77fcfb35c11f726a;hp=c4f919ab862dc436a525d6e56f6385317f0ac062;hpb=ce5ce8ad30a4c4da0a91458f3daa836532c842fa;p=collectd.git diff --git a/src/disk.c b/src/disk.c index c4f919ab..c809fdb6 100644 --- a/src/disk.c +++ b/src/disk.c @@ -101,8 +101,8 @@ typedef struct diskstats /* This overflows in roughly 1361 year */ unsigned int poll_count; - unsigned int read_sectors; - unsigned int write_sectors; + unsigned long long read_sectors; + unsigned long long write_sectors; unsigned long long read_bytes; unsigned long long write_bytes; @@ -111,6 +111,7 @@ typedef struct diskstats } diskstats_t; static diskstats_t *disklist; +static int min_poll_count; /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT @@ -143,7 +144,17 @@ static void disk_init (void) /* #endif HAVE_IOKIT_IOKITLIB_H */ #elif KERNEL_LINUX - /* No init needed */ + int step; + int heartbeat; + + step = atoi (COLLECTD_STEP); + heartbeat = atoi (COLLECTD_HEARTBEAT); + + assert (step > 0); + assert (heartbeat >= step); + + min_poll_count = 1 + (heartbeat / step); + DBG ("min_poll_count = %i;", min_poll_count); /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT @@ -219,6 +230,9 @@ static void disk_submit (char *disk_name, write_time) >= BUFSIZE) return; + DBG ("disk_name = %s; buf = %s;", + disk_name, buf); + plugin_submit (MODULE_NAME, disk_name, buf); } @@ -249,17 +263,14 @@ static signed long long dict_get_value (CFDictionaryRef dict, const char *key) CFNumberRef val_obj; CFStringRef key_obj; - CFStringRef CFStringCreateWithCString ( - CFAllocatorRef alloc, - const char *cStr, - CFStringEncoding encoding - ); - /* `key_obj' needs to be released. */ key_obj = CFStringCreateWithCString (kCFAllocatorDefault, key, kCFStringEncodingASCII); if (key_obj == NULL) + { + DBG ("CFStringCreateWithCString (%s) failed.", key); return (-1LL); + } /* get => we don't need to release (== free) the object */ val_obj = (CFNumberRef) CFDictionaryGetValue (dict, key_obj); @@ -267,11 +278,16 @@ static signed long long dict_get_value (CFDictionaryRef dict, const char *key) CFRelease (key_obj); if (val_obj == NULL) + { + DBG ("CFDictionaryGetValue (%s) failed.", key); return (-1LL); + } - if (CFNumberGetValue (val_obj, kCFNumberSInt64Type, &val_int) - != kIOReturnSuccess) + if (!CFNumberGetValue (val_obj, kCFNumberSInt64Type, &val_int)) + { + DBG ("CFNumberGetValue (%s) failed.", key); return (-1LL); + } return (val_int); } @@ -286,6 +302,7 @@ static void disk_read (void) CFDictionaryRef props_dict; CFDictionaryRef stats_dict; CFDictionaryRef child_dict; + kern_return_t status; signed long long read_ops; signed long long read_byt; @@ -298,14 +315,22 @@ static void disk_read (void) 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) { - syslog (LOG_ERR, "disk-plugin: IOServiceGetMatchingServices failed."); + 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) { @@ -313,6 +338,16 @@ static void disk_read (void) 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, @@ -321,6 +356,7 @@ static void disk_read (void) != kIOReturnSuccess) { syslog (LOG_ERR, "disk-plugin: IORegistryEntryCreateCFProperties failed."); + IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } @@ -328,6 +364,7 @@ static void disk_read (void) if (props_dict == NULL) { DBG ("IORegistryEntryCreateCFProperties (disk) failed."); + IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } @@ -340,16 +377,7 @@ static void disk_read (void) DBG ("CFDictionaryGetValue (%s) failed.", kIOBlockStorageDriverStatisticsKey); CFRelease (props_dict); - IOObjectRelease (disk); - continue; - } - - /* `disk_child' must be released */ - if (IORegistryEntryGetChildEntry (disk, kIOServicePlane, &disk_child) - != kIOReturnSuccess) - { - DBG ("IORegistryEntryGetChildEntry (disk) failed."); - CFRelease (props_dict); + IOObjectRelease (disk_child); IOObjectRelease (disk); continue; } @@ -393,6 +421,7 @@ static void disk_read (void) IOObjectRelease (disk); continue; } + DBG ("disk_name = %s", disk_name); if ((read_ops != -1LL) || (read_byt != -1LL) @@ -424,30 +453,37 @@ static void disk_read (void) int major = 0; int minor = 0; - unsigned int read_sectors; - unsigned int write_sectors; - - unsigned long long read_count = 0; - unsigned long long read_merged = 0; - unsigned long long read_bytes = 0; - unsigned long long read_time = 0; - unsigned long long write_count = 0; - unsigned long long write_merged = 0; - unsigned long long write_bytes = 0; - unsigned long long write_time = 0; + unsigned long long read_sectors = 0ULL; + unsigned long long write_sectors = 0ULL; + + unsigned long long read_count = 0ULL; + unsigned long long read_merged = 0ULL; + unsigned long long read_bytes = 0ULL; + unsigned long long read_time = 0ULL; + unsigned long long write_count = 0ULL; + unsigned long long write_merged = 0ULL; + unsigned long long write_bytes = 0ULL; + unsigned long long write_time = 0ULL; int is_disk = 0; diskstats_t *ds, *pre_ds; + static complain_t complain_obj; + if ((fh = fopen ("/proc/diskstats", "r")) == NULL) { if ((fh = fopen ("/proc/partitions", "r")) == NULL) + { + plugin_complain (LOG_ERR, &complain_obj, "disk plugin: Failed to open /proc/{diskstats,partitions}."); return; + } /* Kernel is 2.4.* */ fieldshift = 1; } + plugin_relief (LOG_NOTICE, &complain_obj, "disk plugin: Succeeded to open /proc/{diskstats,partitions}."); + while (fgets (buffer, 1024, fh) != NULL) { numfields = strsplit (buffer, fields, 32); @@ -488,17 +524,17 @@ static void disk_read (void) { /* Kernel 2.6, Partition */ read_count = atoll (fields[3]); - read_sectors = atoi (fields[4]); + read_sectors = atoll (fields[4]); write_count = atoll (fields[5]); - write_sectors = atoi (fields[6]); + write_sectors = atoll (fields[6]); } else if (numfields == (14 + fieldshift)) { read_count = atoll (fields[3 + fieldshift]); write_count = atoll (fields[7 + fieldshift]); - read_sectors = atoi (fields[5 + fieldshift]); - write_sectors = atoi (fields[9 + fieldshift]); + read_sectors = atoll (fields[5 + fieldshift]); + write_sectors = atoll (fields[9 + fieldshift]); if ((fieldshift == 0) || (minor == 0)) { @@ -511,19 +547,20 @@ static void disk_read (void) } else { + DBG ("numfields = %i; => unknown file format.", numfields); continue; } - - if (read_sectors >= ds->read_sectors) - ds->read_bytes += 512 * (read_sectors - ds->read_sectors); + /* If the counter wraps around, it's only 32 bits.. */ + if (read_sectors < ds->read_sectors) + ds->read_bytes += 512 * ((0xFFFFFFFF - ds->read_sectors) + read_sectors); else - ds->read_bytes += 512 * ((UINT_MAX - ds->read_sectors) + read_sectors); + ds->read_bytes += 512 * (read_sectors - ds->read_sectors); - if (write_sectors >= ds->write_sectors) - ds->write_bytes += 512 * (write_sectors - ds->write_sectors); + if (write_sectors < ds->write_sectors) + ds->write_bytes += 512 * ((0xFFFFFFFF - ds->write_sectors) + write_sectors); else - ds->write_bytes += 512 * ((UINT_MAX - ds->write_sectors) + write_sectors); + ds->write_bytes += 512 * (write_sectors - ds->write_sectors); ds->read_sectors = read_sectors; ds->write_sectors = write_sectors; @@ -532,11 +569,18 @@ static void disk_read (void) /* Don't write to the RRDs if we've just started.. */ ds->poll_count++; - if (ds->poll_count <= 6) + if (ds->poll_count <= min_poll_count) + { + DBG ("(ds->poll_count = %i) <= (min_poll_count = %i); => Not writing.", + ds->poll_count, min_poll_count); continue; + } if ((read_count == 0) && (write_count == 0)) + { + DBG ("((read_count == 0) && (write_count == 0)); => Not writing."); continue; + } if (is_disk) disk_submit (disk_name, read_count, read_merged, read_bytes, read_time,