X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdisk.c;h=85b2329945e929baf6dc733a8510d557382a63a3;hb=8361c1e963f9184c3c4d87197fd6996d667cdb3f;hp=1c3dd98d7d2a93318e8ce0318fbd8acbbd15e016;hpb=1fc00932fd49fa535551cc4bba09c4e4be059ab4;p=collectd.git diff --git a/src/disk.c b/src/disk.c index 1c3dd98d..85b23299 100644 --- a/src/disk.c +++ b/src/disk.c @@ -53,6 +53,10 @@ #if HAVE_IOKIT_IOBSD_H # include #endif +#if KERNEL_FREEBSD +#include +#include +#endif #if HAVE_LIMITS_H # include @@ -107,6 +111,9 @@ typedef struct diskstats static diskstats_t *disklist; /* #endif KERNEL_LINUX */ +#elif KERNEL_FREEBSD +static struct gmesh geom_tree; +/* #endif KERNEL_FREEBSD */ #elif HAVE_LIBKSTAT #define MAX_NUMDISK 1024 @@ -222,6 +229,21 @@ static int disk_init (void) /* do nothing */ /* #endif KERNEL_LINUX */ +#elif KERNEL_FREEBSD + int rv; + + rv = geom_gettree(&geom_tree); + if (rv != 0) { + ERROR ("geom_gettree() failed, returned %d", rv); + return (-1); + } + rv = geom_stats_open(); + if (rv != 0) { + ERROR ("geom_stats_open() failed, returned %d", rv); + return (-1); + } +/* #endif KERNEL_FREEBSD */ + #elif HAVE_LIBKSTAT kstat_t *ksp_chain; @@ -367,7 +389,7 @@ static signed long long dict_get_value (CFDictionaryRef dict, const char *key) DEBUG ("CFStringCreateWithCString (%s) failed.", key); return (-1LL); } - + /* get => we don't need to release (== free) the object */ val_obj = (CFNumberRef) CFDictionaryGetValue (dict, key_obj); @@ -505,10 +527,117 @@ static int disk_read (void) IOObjectRelease (disk_list); /* #endif HAVE_IOKIT_IOKITLIB_H */ +#elif KERNEL_FREEBSD + int retry, dirty; + + void *snap = NULL; + struct devstat *snap_iter; + + struct gident *geom_id; + + const char *disk_name; + long double read_time, write_time; + + for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) { + if (snap != NULL) + geom_stats_snapshot_free(snap); + + /* Get a fresh copy of stats snapshot */ + snap = geom_stats_snapshot_get(); + if (snap == NULL) { + ERROR("disk plugin: geom_stats_snapshot_get() failed."); + return (-1); + } + + /* Check if we have dirty read from this snapshot */ + dirty = 0; + geom_stats_snapshot_reset(snap); + while ((snap_iter = geom_stats_snapshot_next(snap)) != NULL) { + if (snap_iter->id == NULL) + continue; + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + + /* New device? refresh GEOM tree */ + if (geom_id == NULL) { + geom_deletetree(&geom_tree); + if (geom_gettree(&geom_tree) != 0) { + ERROR("disk plugin: geom_gettree() failed"); + geom_stats_snapshot_free(snap); + return (-1); + } + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + } + /* + * This should be rare: the device come right before we take the + * snapshot and went away right after it. We will handle this + * case later, so don't mark dirty but silently ignore it. + */ + if (geom_id == NULL) + continue; + + /* Only collect PROVIDER data */ + if (geom_id->lg_what != ISPROVIDER) + continue; + + /* Only collect data when rank is 1 (physical devices) */ + if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) + continue; + + /* Check if this is a dirty read quit for another try */ + if (snap_iter->sequence0 != snap_iter->sequence1) { + dirty = 1; + break; + } + } + } + + /* Reset iterator */ + geom_stats_snapshot_reset(snap); + for (;;) { + snap_iter = geom_stats_snapshot_next(snap); + if (snap_iter == NULL) + break; + + if (snap_iter->id == NULL) + continue; + geom_id = geom_lookupid(&geom_tree, snap_iter->id); + if (geom_id == NULL) + continue; + if (geom_id->lg_what != ISPROVIDER) + continue; + if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1) + continue; + /* Skip dirty reads, if present */ + if (dirty && (snap_iter->sequence0 != snap_iter->sequence1)) + continue; + + disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name; + + if ((snap_iter->bytes[DEVSTAT_READ] != 0) || (snap_iter->bytes[DEVSTAT_WRITE] != 0)) { + disk_submit(disk_name, "disk_octets", + (derive_t)snap_iter->bytes[DEVSTAT_READ], + (derive_t)snap_iter->bytes[DEVSTAT_WRITE]); + } + + if ((snap_iter->operations[DEVSTAT_READ] != 0) || (snap_iter->operations[DEVSTAT_WRITE] != 0)) { + disk_submit(disk_name, "disk_ops", + (derive_t)snap_iter->operations[DEVSTAT_READ], + (derive_t)snap_iter->operations[DEVSTAT_WRITE]); + } + + read_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_READ], NULL); + write_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_WRITE], NULL); + if ((read_time != 0) || (write_time != 0)) { + disk_submit (disk_name, "disk_time", + (derive_t)(read_time*1000), (derive_t)(write_time*1000)); + } + } + geom_stats_snapshot_free(snap); + #elif KERNEL_LINUX FILE *fh; char buffer[1024]; - + char *fields[32]; int numfields; int fieldshift = 0; @@ -552,7 +681,6 @@ static int disk_read (void) { char *disk_name; char *output_name; - char *alt_name; numfields = strsplit (buffer, fields, 32); @@ -712,13 +840,10 @@ static int disk_read (void) output_name = disk_name; #if HAVE_LIBUDEV - alt_name = disk_udev_attr_name (handle_udev, disk_name, - conf_udev_name_attr); -#else - alt_name = NULL; -#endif + char *alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr); if (alt_name != NULL) output_name = alt_name; +#endif if ((ds->read_bytes != 0) || (ds->write_bytes != 0)) disk_submit (output_name, "disk_octets", @@ -740,8 +865,10 @@ static int disk_read (void) submit_io_time (output_name, io_time, weighted_time); } /* if (is_disk) */ +#if HAVE_LIBUDEV /* release udev-based alternate name, if allocated */ - free(alt_name); + sfree (alt_name); +#endif } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ #if HAVE_LIBUDEV @@ -809,10 +936,10 @@ static int disk_read (void) #endif int counter; char name[DATA_MAX_NAME_LEN]; - + if ((ds = sg_get_disk_io_stats(&disks)) == NULL) return (0); - + for (counter=0; counter < disks; counter++) { strncpy(name, ds->disk_name, sizeof(name)); name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */ @@ -832,7 +959,7 @@ static int disk_read (void) int rnumdisk; int i; - if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) + if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) { char errbuf[1024]; WARNING ("disk plugin: perfstat_disk: %s", @@ -841,14 +968,14 @@ static int disk_read (void) } if (numdisk != pnumdisk || stat_disk==NULL) { - if (stat_disk!=NULL) + if (stat_disk!=NULL) free(stat_disk); stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t)); - } + } pnumdisk = numdisk; firstpath.name[0]='\0'; - if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0) + if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0) { char errbuf[1024]; WARNING ("disk plugin: perfstat_disk : %s", @@ -856,7 +983,7 @@ static int disk_read (void) return (-1); } - for (i = 0; i < rnumdisk; i++) + for (i = 0; i < rnumdisk; i++) { read_sectors = stat_disk[i].rblks*stat_disk[i].bsize; write_sectors = stat_disk[i].wblks*stat_disk[i].bsize;