$NetBSD: patch-ab,v 1.9 2006/08/11 20:40:36 adam Exp $ --- agent/mibgroup/ucd-snmp/diskio.c.orig 2006-08-11 22:32:57.000000000 +0200 +++ agent/mibgroup/ucd-snmp/diskio.c @@ -419,6 +419,155 @@ var_diskio(struct variable * vp, } #endif /* bsdi */ +#ifdef __NetBSD__ +#include +static int ndisk; +#ifdef HW_IOSTATNAMES +static int nmib[2] = {CTL_HW, HW_IOSTATNAMES}; +#else +static int nmib[2] = {CTL_HW, HW_DISKNAMES}; +#endif +#ifdef HW_DISKSTATS +#include +static int dmib[3] = {CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl)}; +static struct disk_sysctl *dk; +#endif +#ifdef HW_IOSTATS +#include +static int dmib[3] = {CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl)}; +static struct io_sysctl *dk; +#endif +static char **dkname; + +static int +getstats(void) +{ + time_t now; + char *t, *tp; + int size, dkn_size, i; + + now = time(NULL); + if (cache_time + CACHE_TIMEOUT > now) { + return 1; + } + size = 0; + if (sysctl(dmib, 3, NULL, &size, NULL, 0) < 0) { + perror("Can't get size of HW_DISKSTATS/HW_IOSTATS mib"); + return 0; + } + if (ndisk != size / dmib[2]) { + if (dk) + free(dk); + if (dkname) { + for (i = 0; i < ndisk; i++) + if (dkname[i]) + free(dkname[i]); + free(dkname); + } + ndisk = size / dmib[2]; + if (ndisk == 0) + return 0; + dkname = malloc(ndisk * sizeof(char *)); + if (sysctl(nmib, 2, NULL, &dkn_size, NULL, 0) < 0) { + perror("Can't get size of HW_DISKNAMES mib"); + return 0; + } + t = malloc(dkn_size); + if (sysctl(nmib, 2, t, &dkn_size, NULL, 0) < 0) { + perror("Can't get size of HW_DISKNAMES mib"); + return 0; + } + for (i = 0, tp = strtok(t, " "); tp && i < ndisk; i++, + tp = strtok(NULL, " ")) { + dkname[i] = strdup(tp); + } + free(t); + dk = malloc(ndisk * sizeof(*dk)); + } + if (sysctl(dmib, 3, dk, &size, NULL, 0) < 0) { + perror("Can't get HW_DISKSTATS/HW_IOSTATS mib"); + return 0; + } + cache_time = now; + return 1; +} + +u_char * +var_diskio(struct variable * vp, + oid * name, + size_t * length, + int exact, size_t * var_len, WriteMethod ** write_method) +{ + static long long_ret; + unsigned int indx; + + if (getstats() == 0) + return 0; + + if (header_simple_table + (vp, name, length, exact, var_len, write_method, ndisk)) + return NULL; + + indx = (unsigned int) (name[*length - 1] - 1); + if (indx >= ndisk) + return NULL; + + switch (vp->magic) { + case DISKIO_INDEX: + long_ret = (long) indx + 1; + return (u_char *) & long_ret; + + case DISKIO_DEVICE: + *var_len = strlen(dkname[indx]); + return (u_char *) dkname[indx]; + + case DISKIO_NREAD: +#ifdef HW_DISKSTATS + long_ret = dk[indx].dk_rbytes; +#endif +#ifdef HW_IOSTATS + if (dk[indx].type == IOSTAT_DISK) + long_ret = dk[indx].rbytes; +#endif + return (u_char *) & long_ret; + + case DISKIO_NWRITTEN: +#ifdef HW_DISKSTATS + long_ret = dk[indx].dk_wbytes; +#endif +#ifdef HW_IOSTATS + if (dk[indx].type == IOSTAT_DISK) + long_ret = dk[indx].wbytes; +#endif + return (u_char *) & long_ret; + + case DISKIO_READS: +#ifdef HW_DISKSTATS + long_ret = dk[indx].dk_rxfer; +#endif +#ifdef HW_IOSTATS + if (dk[indx].type == IOSTAT_DISK) + long_ret = dk[indx].rxfer; +#endif + return (u_char *) & long_ret; + + case DISKIO_WRITES: +#ifdef HW_DISKSTATS + long_ret = dk[indx].dk_wxfer; +#endif +#ifdef HW_IOSTATS + if (dk[indx].type == IOSTAT_DISK) + long_ret = dk[indx].wxfer; +#endif + return (u_char *) & long_ret; + + default: + ERROR_MSG("diskio.c: don't know how to handle this request."); + } + return NULL; +} +#endif /* __NetBSD__ */ + #if defined(freebsd4) || defined(freebsd5) /* disk load average patch by Rojer */