summaryrefslogtreecommitdiff
path: root/net/net-snmp/patches/patch-ab
blob: 186c339883d3c58572b740823671ca877d37437f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
$NetBSD: patch-ab,v 1.10 2010/07/20 08:33:44 adam Exp $

--- agent/mibgroup/ucd-snmp/diskio.c.orig	2009-04-10 20:14:51.000000000 +0000
+++ agent/mibgroup/ucd-snmp/diskio.c
@@ -421,6 +421,155 @@ var_diskio(struct variable * vp,
 }
 #endif                          /* bsdi */
 
+#ifdef __NetBSD__
+#include <sys/sysctl.h>
+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 <sys/disk.h>
+static int dmib[3] = {CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl)};
+static struct disk_sysctl *dk;
+#endif
+#ifdef HW_IOSTATS
+#include <sys/iostat.h>
+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 */