Annotation of src/usr.bin/systat/pool.c, Revision 1.8
1.8 ! mpi 1: /* $OpenBSD: pool.c,v 1.7 2014/07/02 00:12:34 dlg Exp $ */
1.1 canacar 2: /*
3: * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17:
18: #include <sys/types.h>
19: #include <sys/param.h>
20: #include <sys/sysctl.h>
21: #include <sys/pool.h>
22: #include <errno.h>
23: #include <stdlib.h>
1.3 chl 24: #include <string.h>
1.1 canacar 25:
26: #include "systat.h"
27:
28: void print_pool(void);
29: int read_pool(void);
30: void sort_pool(void);
31: int select_pool(void);
32: void showpool(int k);
1.8 ! mpi 33: int pool_keyboard_callback(int);
1.1 canacar 34:
35: /* qsort callbacks */
36: int sort_name_callback(const void *s1, const void *s2);
1.2 canacar 37: int sort_req_callback(const void *s1, const void *s2);
1.4 canacar 38: int sort_psize_callback(const void *s1, const void *s2);
39: int sort_npage_callback(const void *s1, const void *s2);
1.1 canacar 40:
41: struct pool_info {
42: char name[32];
1.7 dlg 43: struct kinfo_pool pool;
1.1 canacar 44: };
45:
46:
1.8 ! mpi 47: int print_all = 0;
1.1 canacar 48: int num_pools = 0;
49: struct pool_info *pools = NULL;
50:
51:
52: field_def fields_pool[] = {
53: {"NAME", 11, 32, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
54: {"SIZE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
55: {"REQUESTS", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
56: {"FAIL", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
57: {"INUSE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
58: {"PGREQ", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
59: {"PGREL", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
60: {"NPAGE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
61: {"HIWAT", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
62: {"MINPG", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
63: {"MAXPG", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
64: {"IDLE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}
65: };
66:
67:
1.6 jasper 68: #define FLD_POOL_NAME FIELD_ADDR(fields_pool,0)
69: #define FLD_POOL_SIZE FIELD_ADDR(fields_pool,1)
70: #define FLD_POOL_REQS FIELD_ADDR(fields_pool,2)
71: #define FLD_POOL_FAIL FIELD_ADDR(fields_pool,3)
72: #define FLD_POOL_INUSE FIELD_ADDR(fields_pool,4)
73: #define FLD_POOL_PGREQ FIELD_ADDR(fields_pool,5)
74: #define FLD_POOL_PGREL FIELD_ADDR(fields_pool,6)
75: #define FLD_POOL_NPAGE FIELD_ADDR(fields_pool,7)
76: #define FLD_POOL_HIWAT FIELD_ADDR(fields_pool,8)
77: #define FLD_POOL_MINPG FIELD_ADDR(fields_pool,9)
78: #define FLD_POOL_MAXPG FIELD_ADDR(fields_pool,10)
79: #define FLD_POOL_IDLE FIELD_ADDR(fields_pool,11)
1.1 canacar 80:
81: /* Define views */
82: field_def *view_pool_0[] = {
83: FLD_POOL_NAME, FLD_POOL_SIZE, FLD_POOL_REQS, FLD_POOL_FAIL,
84: FLD_POOL_INUSE, FLD_POOL_PGREQ, FLD_POOL_PGREL, FLD_POOL_NPAGE,
85: FLD_POOL_HIWAT, FLD_POOL_MINPG, FLD_POOL_MAXPG, FLD_POOL_IDLE, NULL
86: };
87:
88: order_type pool_order_list[] = {
1.2 canacar 89: {"name", "name", 'N', sort_name_callback},
90: {"requests", "requests", 'Q', sort_req_callback},
1.4 canacar 91: {"size", "size", 'Z', sort_psize_callback},
92: {"npages", "npages", 'P', sort_npage_callback},
1.1 canacar 93: {NULL, NULL, 0, NULL}
94: };
95:
96: /* Define view managers */
97: struct view_manager pool_mgr = {
98: "Pool", select_pool, read_pool, sort_pool, print_header,
1.8 ! mpi 99: print_pool, pool_keyboard_callback, pool_order_list, pool_order_list
1.1 canacar 100: };
101:
102: field_view views_pool[] = {
103: {view_pool_0, "pool", '5', &pool_mgr},
104: {NULL, NULL, 0, NULL}
105: };
106:
107:
108: int
109: sort_name_callback(const void *s1, const void *s2)
110: {
111: struct pool_info *p1, *p2;
112: p1 = (struct pool_info *)s1;
113: p2 = (struct pool_info *)s2;
114:
1.2 canacar 115: return strcmp(p1->name, p2->name) * sortdir;
116: }
117:
118: int
119: sort_req_callback(const void *s1, const void *s2)
120: {
121: struct pool_info *p1, *p2;
122: p1 = (struct pool_info *)s1;
123: p2 = (struct pool_info *)s2;
124:
125: if (p1->pool.pr_nget < p2->pool.pr_nget)
126: return sortdir;
127: if (p1->pool.pr_nget > p2->pool.pr_nget)
128: return -sortdir;
129:
130: return sort_name_callback(s1, s2);
1.4 canacar 131: }
132:
133: int
134: sort_npage_callback(const void *s1, const void *s2)
135: {
136: struct pool_info *p1, *p2;
137: p1 = (struct pool_info *)s1;
138: p2 = (struct pool_info *)s2;
139:
140: if (p1->pool.pr_npages < p2->pool.pr_npages)
141: return sortdir;
142: if (p1->pool.pr_npages > p2->pool.pr_npages)
143: return -sortdir;
144:
145: return sort_name_callback(s1, s2);
146: }
147:
148: int
149: sort_psize_callback(const void *s1, const void *s2)
150: {
151: struct pool_info *p1, *p2;
152: size_t ps1, ps2;
153:
154: p1 = (struct pool_info *)s1;
155: p2 = (struct pool_info *)s2;
156:
157: ps1 = (size_t)(p1->pool.pr_nget - p1->pool.pr_nput) *
158: (size_t)p1->pool.pr_size;
159: ps2 = (size_t)(p2->pool.pr_nget - p2->pool.pr_nput) *
160: (size_t)p2->pool.pr_size;
161:
162: if (ps1 < ps2)
163: return sortdir;
164: if (ps1 > ps2)
165: return -sortdir;
166:
167: return sort_npage_callback(s1, s2);
1.1 canacar 168: }
169:
170: void
171: sort_pool(void)
172: {
173: order_type *ordering;
174:
175: if (curr_mgr == NULL)
176: return;
177:
178: ordering = curr_mgr->order_curr;
179:
180: if (ordering == NULL)
181: return;
182: if (ordering->func == NULL)
183: return;
184: if (pools == NULL)
185: return;
186: if (num_pools <= 0)
187: return;
188:
1.2 canacar 189: mergesort(pools, num_pools, sizeof(struct pool_info), ordering->func);
1.1 canacar 190: }
191:
192: int
193: select_pool(void)
194: {
195: num_disp = num_pools;
196: return (0);
197: }
198:
199: int
200: read_pool(void)
201: {
202: int mib[4], np, i;
203: size_t size;
204:
205: mib[0] = CTL_KERN;
206: mib[1] = KERN_POOL;
207: mib[2] = KERN_POOL_NPOOLS;
208: size = sizeof(np);
209:
210: if (sysctl(mib, 3, &np, &size, NULL, 0) < 0) {
211: error("sysctl(npools): %s", strerror(errno));
212: return (-1);
213: }
214:
215: if (np <= 0) {
216: num_pools = 0;
217: return (0);
218: }
219:
220: if (np > num_pools || pools == NULL) {
221: struct pool_info *p = realloc(pools, sizeof(*pools) * np);
222: if (p == NULL) {
223: error("realloc: %s", strerror(errno));
224: return (-1);
225: }
226: pools = p;
227: num_pools = np;
228: }
229:
1.5 canacar 230: num_disp = num_pools;
231:
1.1 canacar 232: for (i = 0; i < num_pools; i++) {
233: mib[0] = CTL_KERN;
234: mib[1] = KERN_POOL;
235: mib[2] = KERN_POOL_POOL;
236: mib[3] = i + 1;
1.7 dlg 237: size = sizeof(pools[i].pool);
1.1 canacar 238: if (sysctl(mib, 4, &pools[i].pool, &size, NULL, 0) < 0) {
1.5 canacar 239: memset(&pools[i], 0, sizeof(pools[i]));
240: num_disp--;
241: continue;
1.1 canacar 242: }
243: mib[2] = KERN_POOL_NAME;
244: size = sizeof(pools[i].name);
245: if (sysctl(mib, 4, &pools[i].name, &size, NULL, 0) < 0) {
1.5 canacar 246: snprintf(pools[i].name, size, "#%d#", mib[3]);
1.1 canacar 247: }
248: }
249:
250: if (i != num_pools) {
251: memset(pools, 0, sizeof(*pools) * num_pools);
252: return (-1);
253: }
254:
255: return 0;
256: }
257:
258:
259: void
260: print_pool(void)
261: {
1.8 ! mpi 262: struct pool_info *p;
1.5 canacar 263: int i, n, count = 0;
1.1 canacar 264:
265: if (pools == NULL)
266: return;
267:
1.5 canacar 268: for (n = i = 0; i < num_pools; i++) {
1.8 ! mpi 269: p = &pools[i];
! 270: if (p->name[0] == 0)
1.5 canacar 271: continue;
1.8 ! mpi 272:
! 273: if (!print_all &&
! 274: (p->pool.pr_nget == 0 && p->pool.pr_npagealloc == 0))
! 275: continue;
! 276:
1.5 canacar 277: if (n++ < dispstart)
278: continue;
279: showpool(i);
1.1 canacar 280: count++;
281: if (maxprint > 0 && count >= maxprint)
282: break;
283: }
284: }
285:
286: int
287: initpool(void)
288: {
289: field_view *v;
290:
291: for (v = views_pool; v->name != NULL; v++)
292: add_view(v);
293:
294: read_pool();
295:
296: return(0);
297: }
298:
299: void
300: showpool(int k)
301: {
302: struct pool_info *p = pools + k;
303:
304: if (k < 0 || k >= num_pools)
305: return;
306:
307: print_fld_str(FLD_POOL_NAME, p->name);
308: print_fld_uint(FLD_POOL_SIZE, p->pool.pr_size);
309:
310: print_fld_size(FLD_POOL_REQS, p->pool.pr_nget);
311: print_fld_size(FLD_POOL_FAIL, p->pool.pr_nfail);
312: print_fld_ssize(FLD_POOL_INUSE, p->pool.pr_nget - p->pool.pr_nput);
313: print_fld_size(FLD_POOL_PGREQ, p->pool.pr_npagealloc);
314: print_fld_size(FLD_POOL_PGREL, p->pool.pr_npagefree);
315:
316: print_fld_size(FLD_POOL_NPAGE, p->pool.pr_npages);
317: print_fld_size(FLD_POOL_HIWAT, p->pool.pr_hiwat);
318: print_fld_size(FLD_POOL_MINPG, p->pool.pr_minpages);
319:
320: if (p->pool.pr_maxpages == UINT_MAX)
321: print_fld_str(FLD_POOL_MAXPG, "inf");
322: else
323: print_fld_size(FLD_POOL_MAXPG, p->pool.pr_maxpages);
324:
325: print_fld_size(FLD_POOL_IDLE, p->pool.pr_nidle);
326:
327: end_line();
1.8 ! mpi 328: }
! 329:
! 330: int
! 331: pool_keyboard_callback(int ch)
! 332: {
! 333: switch (ch) {
! 334: case 'A':
! 335: print_all ^= 1;
! 336: gotsig_alarm = 1;
! 337: default:
! 338: return keyboard_callback(ch);
! 339: };
! 340:
! 341: return (1);
1.1 canacar 342: }