1 /*
2 * Copyright (c) 2003 Daniel Hartmeier
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31 #include <sys/param.h>
32 #include <sys/mbuf.h>
33 #include <sys/sysctl.h>
34 #include <sys/errno.h>
35
36 #include <errno.h>
37 #include <string.h>
38 #include <unistd.h>
39
40 #include "conf.h"
41 #include "error.h"
42 #include "symon.h"
43
44 #ifndef HAS_KERN_MBSTAT
45 void
init_mbuf(struct stream * st)46 init_mbuf(struct stream *st)
47 {
48 fatal("mbuf module requires system upgrade (sysctl.h/KERN_MBSTAT)");
49 }
50 int
get_mbuf(char * symon_buf,int maxlen,struct stream * st)51 get_mbuf(char *symon_buf, int maxlen, struct stream *st)
52 {
53 fatal("mbuf module requires system upgrade (sysctl.h/KERN_MBSTAT)");
54 }
55 #else
56 void
init_mbuf(struct stream * st)57 init_mbuf(struct stream *st)
58 {
59 info("started module mbuf(%.200s)", st->arg);
60 }
61
62 int
get_mbuf(char * symon_buf,int maxlen,struct stream * st)63 get_mbuf(char *symon_buf, int maxlen, struct stream *st)
64 {
65 struct mbstat mbstat;
66 int npools;
67 struct pool pool, mbpool, mclpool;
68 int mib[4];
69 size_t size;
70 int i;
71 char name[32];
72 int flag = 0;
73 int nmbtypes = sizeof(mbstat.m_mtypes) / sizeof(short);
74 int page_size = getpagesize();
75 int totmem, totused, totmbufs, totpct;
76 u_int32_t stats[15];
77
78 totmem = totused = 0;
79
80 mib[0] = CTL_KERN;
81 mib[1] = KERN_MBSTAT;
82 size = sizeof(mbstat);
83 if (sysctl(mib, 2, &mbstat, &size, NULL, 0) < 0) {
84 warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
85 return 0;
86 }
87
88 mib[0] = CTL_KERN;
89 mib[1] = KERN_POOL;
90 mib[2] = KERN_POOL_NPOOLS;
91 size = sizeof(npools);
92 if (sysctl(mib, 3, &npools, &size, NULL, 0) < 0) {
93 warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
94 return 0;
95 }
96
97 for (i = 1; npools; ++i) {
98 mib[0] = CTL_KERN;
99 mib[1] = KERN_POOL;
100 mib[2] = KERN_POOL_POOL;
101 mib[3] = i;
102 size = sizeof(pool);
103 if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
104 warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
105 return 0;
106 }
107 npools--;
108 mib[2] = KERN_POOL_NAME;
109 size = sizeof(name);
110 if (sysctl(mib, 4, name, &size, NULL, 0) < 0) {
111 warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
112 return (0);
113 }
114 if (!strcmp(name, "mbpl")) {
115 bcopy(&pool, &mbpool, sizeof(pool));
116 flag |= (1 << 0);
117 } else if (!strcmp(name, "mclpl")) {
118 bcopy(&pool, &mclpool, sizeof(pool));
119 totmem += mclpool.pr_npages * page_size;
120 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
121 flag |= (1 << 1);
122 } else if (!strcmp(name, "mcl2k")) {
123 bcopy(&pool, &mclpool, sizeof(pool));
124 totmem += mclpool.pr_npages * page_size;
125 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
126 flag |= (1 << 2);
127 } else if (!strcmp(name, "mcl4k")) {
128 bcopy(&pool, &mclpool, sizeof(pool));
129 totmem += mclpool.pr_npages * page_size;
130 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
131 flag |= (1 << 3);
132 } else if (!strcmp(name, "mcl8k")) {
133 bcopy(&pool, &mclpool, sizeof(pool));
134 totmem += mclpool.pr_npages * page_size;
135 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
136 flag |= (1 << 4);
137 } else if (!strcmp(name, "mcl9k")) {
138 bcopy(&pool, &mclpool, sizeof(pool));
139 totmem += mclpool.pr_npages * page_size;
140 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
141 flag |= (1 << 5);
142 } else if (!strcmp(name, "mcl12k")) {
143 bcopy(&pool, &mclpool, sizeof(pool));
144 totmem += mclpool.pr_npages * page_size;
145 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
146 flag |= (1 << 6);
147 } else if (!strcmp(name, "mcl16k")) {
148 bcopy(&pool, &mclpool, sizeof(pool));
149 totmem += mclpool.pr_npages * page_size;
150 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
151 flag |= (1 << 7);
152 } else if (!strcmp(name, "mcl64k")) {
153 bcopy(&pool, &mclpool, sizeof(pool));
154 totmem += mclpool.pr_npages * page_size;
155 totused += (mclpool.pr_nget - mclpool.pr_nput) * mclpool.pr_size;
156 flag |= (1 << 8);
157 }
158 if (flag == 3 || flag == 509)
159 break;
160 }
161
162 /* Check pre/post h2k8 mcpl */
163 if ((flag != 3) && (flag != 509)) {
164 warning("mbuf(%.200s) failed (%d)", st->arg, flag);
165 return 0;
166 }
167
168 totmbufs = 0;
169 for (i = 0; i < nmbtypes; ++i)
170 totmbufs += mbstat.m_mtypes[i];
171 totmem += mbpool.pr_npages * page_size;
172 totused += (mbpool.pr_nget - mbpool.pr_nput) * mbpool.pr_size;
173 totpct = (totmem == 0) ? 0 : ((totused * 100) / totmem);
174
175 stats[0] = totmbufs;
176 stats[1] = mbstat.m_mtypes[MT_DATA];
177 stats[2] = mbstat.m_mtypes[MT_OOBDATA];
178 stats[3] = mbstat.m_mtypes[MT_CONTROL];
179 stats[4] = mbstat.m_mtypes[MT_HEADER];
180 stats[5] = mbstat.m_mtypes[MT_FTABLE];
181 stats[6] = mbstat.m_mtypes[MT_SONAME];
182 stats[7] = mbstat.m_mtypes[MT_SOOPTS];
183 stats[8] = mclpool.pr_nget - mclpool.pr_nput;
184 stats[9] = mclpool.pr_npages * mclpool.pr_itemsperpage;
185 stats[10] = totmem;
186 stats[11] = totpct;
187 stats[12] = mbstat.m_drops;
188 stats[13] = mbstat.m_wait;
189 stats[14] = mbstat.m_drain;
190
191 return snpack(symon_buf, maxlen, st->arg, MT_MBUF,
192 stats[0],
193 stats[1],
194 stats[2],
195 stats[3],
196 stats[4],
197 stats[5],
198 stats[6],
199 stats[7],
200 stats[8],
201 stats[9],
202 stats[10],
203 stats[11],
204 stats[12],
205 stats[13],
206 stats[14]);
207 }
208 #endif /* HAS_KERN_MBSTAT */
209