diff options
Diffstat (limited to 'usr.bin/systat/pool.c')
-rw-r--r-- | usr.bin/systat/pool.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/usr.bin/systat/pool.c b/usr.bin/systat/pool.c new file mode 100644 index 00000000000..c6bbede69dc --- /dev/null +++ b/usr.bin/systat/pool.c @@ -0,0 +1,256 @@ +/* $OpenBSD: pool.c,v 1.1 2008/11/02 06:23:28 canacar Exp $ */ +/* + * Copyright (c) 2008 Can Erkin Acar <canacar@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/pool.h> +#include <errno.h> +#include <stdlib.h> + +#include "systat.h" + +void print_pool(void); +int read_pool(void); +void sort_pool(void); +int select_pool(void); +void showpool(int k); + +/* qsort callbacks */ +int sort_name_callback(const void *s1, const void *s2); + +struct pool_info { + char name[32]; + struct pool pool; +}; + + +int num_pools = 0; +struct pool_info *pools = NULL; + + +field_def fields_pool[] = { + {"NAME", 11, 32, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, + {"SIZE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"REQUESTS", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"FAIL", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"INUSE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"PGREQ", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"PGREL", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"NPAGE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"HIWAT", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"MINPG", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"MAXPG", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0}, + {"IDLE", 8, 24, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0} +}; + + +#define FIELD_ADDR(x) (&fields_pool[x]) + +#define FLD_POOL_NAME FIELD_ADDR(0) +#define FLD_POOL_SIZE FIELD_ADDR(1) +#define FLD_POOL_REQS FIELD_ADDR(2) +#define FLD_POOL_FAIL FIELD_ADDR(3) +#define FLD_POOL_INUSE FIELD_ADDR(4) +#define FLD_POOL_PGREQ FIELD_ADDR(5) +#define FLD_POOL_PGREL FIELD_ADDR(6) +#define FLD_POOL_NPAGE FIELD_ADDR(7) +#define FLD_POOL_HIWAT FIELD_ADDR(8) +#define FLD_POOL_MINPG FIELD_ADDR(9) +#define FLD_POOL_MAXPG FIELD_ADDR(10) +#define FLD_POOL_IDLE FIELD_ADDR(11) + +/* Define views */ +field_def *view_pool_0[] = { + FLD_POOL_NAME, FLD_POOL_SIZE, FLD_POOL_REQS, FLD_POOL_FAIL, + FLD_POOL_INUSE, FLD_POOL_PGREQ, FLD_POOL_PGREL, FLD_POOL_NPAGE, + FLD_POOL_HIWAT, FLD_POOL_MINPG, FLD_POOL_MAXPG, FLD_POOL_IDLE, NULL +}; + +order_type pool_order_list[] = { + {"name", "name", 0, sort_name_callback}, + {NULL, NULL, 0, NULL} +}; + +/* Define view managers */ +struct view_manager pool_mgr = { + "Pool", select_pool, read_pool, sort_pool, print_header, + print_pool, keyboard_callback, pool_order_list, pool_order_list +}; + +field_view views_pool[] = { + {view_pool_0, "pool", '5', &pool_mgr}, + {NULL, NULL, 0, NULL} +}; + + +int +sort_name_callback(const void *s1, const void *s2) +{ + struct pool_info *p1, *p2; + p1 = (struct pool_info *)s1; + p2 = (struct pool_info *)s2; + + return strcmp(p1->name, p2->name); +} + +void +sort_pool(void) +{ + order_type *ordering; + + if (curr_mgr == NULL) + return; + + ordering = curr_mgr->order_curr; + + if (ordering == NULL) + return; + if (ordering->func == NULL) + return; + if (pools == NULL) + return; + if (num_pools <= 0) + return; + + qsort(pools, num_pools, sizeof(struct pool_info), ordering->func); +} + +int +select_pool(void) +{ + num_disp = num_pools; + return (0); +} + +int +read_pool(void) +{ + int mib[4], np, i; + size_t size; + + mib[0] = CTL_KERN; + mib[1] = KERN_POOL; + mib[2] = KERN_POOL_NPOOLS; + size = sizeof(np); + + if (sysctl(mib, 3, &np, &size, NULL, 0) < 0) { + error("sysctl(npools): %s", strerror(errno)); + return (-1); + } + + if (np <= 0) { + num_pools = 0; + return (0); + } + + if (np > num_pools || pools == NULL) { + struct pool_info *p = realloc(pools, sizeof(*pools) * np); + if (p == NULL) { + error("realloc: %s", strerror(errno)); + return (-1); + } + pools = p; + num_pools = np; + } + + for (i = 0; i < num_pools; i++) { + mib[0] = CTL_KERN; + mib[1] = KERN_POOL; + mib[2] = KERN_POOL_POOL; + mib[3] = i + 1; + size = sizeof(struct pool); + if (sysctl(mib, 4, &pools[i].pool, &size, NULL, 0) < 0) { + error("sysctl(pool): %s", strerror(errno)); + break; + } + mib[2] = KERN_POOL_NAME; + size = sizeof(pools[i].name); + if (sysctl(mib, 4, &pools[i].name, &size, NULL, 0) < 0) { + error("sysctl(pool_name): %s", strerror(errno)); + break; + } + } + + if (i != num_pools) { + memset(pools, 0, sizeof(*pools) * num_pools); + return (-1); + } + + return 0; +} + + +void +print_pool(void) +{ + int n, count = 0; + + if (pools == NULL) + return; + + for (n = dispstart; n < num_disp; n++) { + showpool(n); + count++; + if (maxprint > 0 && count >= maxprint) + break; + } +} + +int +initpool(void) +{ + field_view *v; + + for (v = views_pool; v->name != NULL; v++) + add_view(v); + + read_pool(); + + return(0); +} + +void +showpool(int k) +{ + struct pool_info *p = pools + k; + + if (k < 0 || k >= num_pools) + return; + + print_fld_str(FLD_POOL_NAME, p->name); + print_fld_uint(FLD_POOL_SIZE, p->pool.pr_size); + + print_fld_size(FLD_POOL_REQS, p->pool.pr_nget); + print_fld_size(FLD_POOL_FAIL, p->pool.pr_nfail); + print_fld_ssize(FLD_POOL_INUSE, p->pool.pr_nget - p->pool.pr_nput); + print_fld_size(FLD_POOL_PGREQ, p->pool.pr_npagealloc); + print_fld_size(FLD_POOL_PGREL, p->pool.pr_npagefree); + + print_fld_size(FLD_POOL_NPAGE, p->pool.pr_npages); + print_fld_size(FLD_POOL_HIWAT, p->pool.pr_hiwat); + print_fld_size(FLD_POOL_MINPG, p->pool.pr_minpages); + + if (p->pool.pr_maxpages == UINT_MAX) + print_fld_str(FLD_POOL_MAXPG, "inf"); + else + print_fld_size(FLD_POOL_MAXPG, p->pool.pr_maxpages); + + print_fld_size(FLD_POOL_IDLE, p->pool.pr_nidle); + + end_line(); +} |