opensolaris_kstat.c revision 321529
1/*- 2 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> 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 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/11/sys/cddl/compat/opensolaris/kern/opensolaris_kstat.c 321529 2017-07-26 16:14:05Z mav $"); 29 30#include <sys/param.h> 31#include <sys/kernel.h> 32#include <sys/systm.h> 33#include <sys/malloc.h> 34#include <sys/sysctl.h> 35#include <sys/kstat.h> 36 37static MALLOC_DEFINE(M_KSTAT, "kstat_data", "Kernel statistics"); 38 39SYSCTL_ROOT_NODE(OID_AUTO, kstat, CTLFLAG_RW, 0, "Kernel statistics"); 40 41kstat_t * 42kstat_create(char *module, int instance, char *name, char *class, uchar_t type, 43 ulong_t ndata, uchar_t flags) 44{ 45 struct sysctl_oid *root; 46 kstat_t *ksp; 47 48 KASSERT(instance == 0, ("instance=%d", instance)); 49 KASSERT(type == KSTAT_TYPE_NAMED, ("type=%hhu", type)); 50 KASSERT(flags == KSTAT_FLAG_VIRTUAL, ("flags=%02hhx", flags)); 51 52 /* 53 * Allocate the main structure. We don't need to copy module/class/name 54 * stuff in here, because it is only used for sysctl node creation 55 * done in this function. 56 */ 57 ksp = malloc(sizeof(*ksp), M_KSTAT, M_WAITOK); 58 ksp->ks_ndata = ndata; 59 60 /* 61 * Create sysctl tree for those statistics: 62 * 63 * kstat.<module>.<class>.<name>. 64 */ 65 sysctl_ctx_init(&ksp->ks_sysctl_ctx); 66 root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, 67 SYSCTL_STATIC_CHILDREN(_kstat), OID_AUTO, module, CTLFLAG_RW, 0, 68 ""); 69 if (root == NULL) { 70 printf("%s: Cannot create kstat.%s tree!\n", __func__, module); 71 sysctl_ctx_free(&ksp->ks_sysctl_ctx); 72 free(ksp, M_KSTAT); 73 return (NULL); 74 } 75 root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, SYSCTL_CHILDREN(root), 76 OID_AUTO, class, CTLFLAG_RW, 0, ""); 77 if (root == NULL) { 78 printf("%s: Cannot create kstat.%s.%s tree!\n", __func__, 79 module, class); 80 sysctl_ctx_free(&ksp->ks_sysctl_ctx); 81 free(ksp, M_KSTAT); 82 return (NULL); 83 } 84 root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, SYSCTL_CHILDREN(root), 85 OID_AUTO, name, CTLFLAG_RW, 0, ""); 86 if (root == NULL) { 87 printf("%s: Cannot create kstat.%s.%s.%s tree!\n", __func__, 88 module, class, name); 89 sysctl_ctx_free(&ksp->ks_sysctl_ctx); 90 free(ksp, M_KSTAT); 91 return (NULL); 92 } 93 ksp->ks_sysctl_root = root; 94 95 return (ksp); 96} 97 98static int 99kstat_sysctl(SYSCTL_HANDLER_ARGS) 100{ 101 kstat_named_t *ksent = arg1; 102 uint64_t val; 103 104 val = ksent->value.ui64; 105 return sysctl_handle_64(oidp, &val, 0, req); 106} 107 108void 109kstat_install(kstat_t *ksp) 110{ 111 kstat_named_t *ksent; 112 u_int i; 113 114 ksent = ksp->ks_data; 115 for (i = 0; i < ksp->ks_ndata; i++, ksent++) { 116 KASSERT(ksent->data_type == KSTAT_DATA_UINT64, 117 ("data_type=%d", ksent->data_type)); 118 SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx, 119 SYSCTL_CHILDREN(ksp->ks_sysctl_root), OID_AUTO, ksent->name, 120 CTLTYPE_U64 | CTLFLAG_RD, ksent, sizeof(*ksent), 121 kstat_sysctl, "QU", ksent->desc); 122 } 123} 124 125void 126kstat_delete(kstat_t *ksp) 127{ 128 129 sysctl_ctx_free(&ksp->ks_sysctl_ctx); 130 free(ksp, M_KSTAT); 131} 132 133void 134kstat_set_string(char *dst, const char *src) 135{ 136 137 bzero(dst, KSTAT_STRLEN); 138 (void) strncpy(dst, src, KSTAT_STRLEN - 1); 139} 140 141void 142kstat_named_init(kstat_named_t *knp, const char *name, uchar_t data_type) 143{ 144 145 kstat_set_string(knp->name, name); 146 knp->data_type = data_type; 147} 148