static int req_width(kstat_t *req, int field_width) { int i, nreq, per, len; char fixlen[128]; kstat_named_t *knp; uint64_t tot; tot = 0; knp = KSTAT_NAMED_PTR(req); for (i = 0; i < req->ks_ndata; i++) tot += knp[i].value.ui64; knp = kstat_data_lookup(req, "null"); nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req)); for (i = 0; i < nreq; i++) { len = strlen(knp[i].name) + 1; if (field_width < len) field_width = len; if (tot) per = (int)(knp[i].value.ui64 * 100 / tot); else per = 0; (void) sprintf(fixlen, "%" PRIu64 " %d%%", knp[i].value.ui64, per); len = strlen(fixlen) + 1; if (field_width < len) field_width = len; } return (field_width); }
static void stat_print(const char *title_string, kstat_t *req, kstat_t *req_old, int field_width, int zflag) { int i, j, nreq, ncolumns; char fixlen[128]; kstat_named_t *knp; kstat_named_t *knp_old; if (req == NULL) return; if (field_width == 0) return; printf("%s\n", title_string); ncolumns = (MAX_COLUMNS -1)/field_width; /* MEANS knp = (kstat_named_t *)req->ks_data */ knp = KSTAT_NAMED_PTR(req); nreq = req->ks_ndata; knp_old = KSTAT_NAMED_PTR(req_old); for (i = 0; i < nreq; i += ncolumns) { /* prints out the titles of the columns */ for (j = i; j < MIN(i + ncolumns, nreq); j++) { printf("%-*s", field_width, knp[j].name); } printf("\n"); /* prints out the stat numbers */ for (j = i; j < MIN(i + ncolumns, nreq); j++) { (void) sprintf(fixlen, "%" PRIu64 " ", (interval && knp_old != NULL) ? (knp[j].value.ui64 - knp_old[j].value.ui64) : knp[j].value.ui64); printf("%-*s", field_width, fixlen); } printf("\n"); } if (zflag) { for (i = 0; i < req->ks_ndata; i++) knp[i].value.ui64 = 0; } if (knp_old != NULL) kstat_copy(req, req_old, 1); else kstat_copy(req, req_old, 0); }
void * kstat_data_lookup(kstat_t *ksp, char *name) { int i, size; char *namep, *datap; switch (ksp->ks_type) { case KSTAT_TYPE_NAMED: size = sizeof (kstat_named_t); namep = KSTAT_NAMED_PTR(ksp)->name; break; case KSTAT_TYPE_TIMER: size = sizeof (kstat_timer_t); namep = KSTAT_TIMER_PTR(ksp)->name; break; default: errno = EINVAL; return (NULL); } datap = ksp->ks_data; for (i = 0; i < ksp->ks_ndata; i++) { if (strcmp(name, namep) == 0) return (datap); namep += size; datap += size; } errno = ENOENT; return (NULL); }
static void kstat_sum(kstat_t *kstat1, kstat_t *kstat2, kstat_t *sum) { int i; kstat_named_t *knp1, *knp2, *knpsum; if (kstat1 == NULL || kstat2 == NULL) return; knp1 = KSTAT_NAMED_PTR(kstat1); knp2 = KSTAT_NAMED_PTR(kstat2); if (sum->ks_data == NULL) kstat_copy(kstat1, sum, 0); knpsum = KSTAT_NAMED_PTR(sum); for (i = 0; i < (kstat1->ks_ndata); i++) knpsum[i].value.ui64 = knp1[i].value.ui64 + knp2[i].value.ui64; }
static int get_kstat_vals(kstat_t *ksp, nvlist_t *stats) { if (ksp->ks_type == KSTAT_TYPE_IO) { kstat_io_t *kiop; kiop = KSTAT_IO_PTR(ksp); /* see sys/kstat.h kstat_io_t struct for more fields */ if (update_stat64(stats, DM_NBYTESREAD, kiop->nread) != 0) { return (ENOMEM); } if (update_stat64(stats, DM_NBYTESWRITTEN, kiop->nwritten) != 0) { return (ENOMEM); } if (update_stat64(stats, DM_NREADOPS, kiop->reads) != 0) { return (ENOMEM); } if (update_stat64(stats, DM_NWRITEOPS, kiop->writes) != 0) { return (ENOMEM); } } else if (ksp->ks_type == KSTAT_TYPE_NAMED) { kstat_named_t *knp; int i; knp = KSTAT_NAMED_PTR(ksp); for (i = 0; i < ksp->ks_ndata; i++) { char *attr_name; if (knp[i].name[0] == 0) continue; if ((attr_name = get_err_attr_name(knp[i].name)) == NULL) { continue; } switch (knp[i].data_type) { case KSTAT_DATA_UINT32: if (update_stat32(stats, attr_name, knp[i].value.ui32) != 0) { return (ENOMEM); } break; default: /* Right now all of the error types are uint32 */ break; } } } return (0); }
/* * The kstat needs to be held when calling this function. */ static int softmac_get_kstat(kstat_t *ksp, char *name, uint64_t *valp) { kstat_named_t *knp; int i; int ret = ENOTSUP; if (name == NULL) return (ret); /* * Search the kstat with the given name. */ for (i = 0, knp = KSTAT_NAMED_PTR(ksp); i < ksp->ks_ndata; i++, knp++) { if (strcmp(knp->name, name) == 0) { switch (knp->data_type) { case KSTAT_DATA_INT32: case KSTAT_DATA_UINT32: *valp = (uint64_t)(knp->value.ui32); ret = 0; break; case KSTAT_DATA_INT64: case KSTAT_DATA_UINT64: *valp = knp->value.ui64; ret = 0; break; #ifdef _LP64 case KSTAT_DATA_LONG: case KSTAT_DATA_ULONG: *valp = (uint64_t)knp->value.ul; ret = 0; break; #endif case KSTAT_DATA_CHAR: if (strcmp(name, "duplex") != 0) break; if (strncmp(knp->value.c, "full", 4) == 0) *valp = LINK_DUPLEX_FULL; else if (strncmp(knp->value.c, "half", 4) == 0) *valp = LINK_DUPLEX_HALF; else *valp = LINK_DUPLEX_UNKNOWN; ret = 0; break; } break; } } return (ret); }
kid_t kstat_write(kstat_ctl_t *kc, kstat_t *ksp, void *data) { kid_t kcid; if (ksp->ks_data == NULL && ksp->ks_data_size > 0) { kstat_zalloc(&ksp->ks_data, ksp->ks_data_size, 0); if (ksp->ks_data == NULL) return (-1); } if (data != NULL) { (void) memcpy(ksp->ks_data, data, ksp->ks_data_size); if (ksp->ks_type == KSTAT_TYPE_NAMED) { kstat_named_t *oknp = data; kstat_named_t *nknp = KSTAT_NAMED_PTR(ksp); uint_t i; for (i = 0; i < ksp->ks_ndata; i++, oknp++, nknp++) { if (nknp->data_type != KSTAT_DATA_STRING) continue; if (KSTAT_NAMED_STR_PTR(nknp) == NULL) continue; /* * The buffer passed in as 'data' has string * pointers that point within 'data'. Fix the * pointers so they point into the same offset * within the newly allocated buffer. */ KSTAT_NAMED_STR_PTR(nknp) = (char *)ksp->ks_data + (KSTAT_NAMED_STR_PTR(oknp) - (char *)data); } } } while ((kcid = (kid_t)ioctl(kc->kc_kd, KSTAT_IOC_WRITE, ksp)) == -1) { if (errno == EAGAIN) { (void) poll(NULL, 0, 100); /* back off a moment */ continue; /* and try again */ } break; } return (kcid); }
static int stat_width(kstat_t *req, int field_width) { int i, nreq, len; char fixlen[128]; kstat_named_t *knp; knp = KSTAT_NAMED_PTR(req); nreq = req->ks_ndata; for (i = 0; i < nreq; i++) { len = strlen(knp[i].name) + 1; if (field_width < len) field_width = len; (void) sprintf(fixlen, "%" PRIu64, knp[i].value.ui64); len = strlen(fixlen) + 1; if (field_width < len) field_width = len; } return (field_width); }
static void save_named(ks_returner_t *ret, kstat_t *kp, ks_instance_t *ksi) { kstat_named_t *knp; int n; for (n = kp->ks_ndata, knp = KSTAT_NAMED_PTR(kp); n > 0; n--, knp++) { switch (knp->data_type) { case KSTAT_DATA_CHAR: nvpair_insert(ret, ksi, knp->name, (ks_value_t *)&knp->value, KSTAT_DATA_CHAR); break; case KSTAT_DATA_INT32: nvpair_insert(ret, ksi, knp->name, (ks_value_t *)&knp->value, KSTAT_DATA_INT32); break; case KSTAT_DATA_UINT32: nvpair_insert(ret, ksi, knp->name, (ks_value_t *)&knp->value, KSTAT_DATA_UINT32); break; case KSTAT_DATA_INT64: nvpair_insert(ret, ksi, knp->name, (ks_value_t *)&knp->value, KSTAT_DATA_INT64); break; case KSTAT_DATA_UINT64: nvpair_insert(ret, ksi, knp->name, (ks_value_t *)&knp->value, KSTAT_DATA_UINT64); break; case KSTAT_DATA_STRING: SAVE_STRING_X(ret, ksi, knp->name, KSTAT_NAMED_STR_PTR(knp)); break; default: assert(B_FALSE); /* Invalid data type */ break; } } }
static void req_print_v4(kstat_t *req, kstat_t *req_old, int field_width, int zflag) { int i, j, nreq, per, ncolumns; uint64_t tot, tot_ops, old_tot, old_tot_ops; char fixlen[128]; kstat_named_t *kptr; kstat_named_t *knp; kstat_named_t *kptr_old; if (req == NULL) return; if (field_width == 0) return; ncolumns = (MAX_COLUMNS)/field_width; kptr = KSTAT_NAMED_PTR(req); kptr_old = KSTAT_NAMED_PTR(req_old); if (kptr_old == NULL) { old_tot_ops = 0; old_tot = 0; } else { old_tot = kptr_old[0].value.ui64 + kptr_old[1].value.ui64; for (i = 2, old_tot_ops = 0; i < req_old->ks_ndata; i++) old_tot_ops += kptr_old[i].value.ui64; } /* Count the number of operations sent */ for (i = 2, tot_ops = 0; i < req->ks_ndata; i++) tot_ops += kptr[i].value.ui64; /* For v4 NULL/COMPOUND are the only procedures */ tot = kptr[0].value.ui64 + kptr[1].value.ui64; if (interval) { tot -= old_tot; tot_ops -= old_tot_ops; } printf("Version 4: (%" PRIu64 " calls)\n", tot); knp = kstat_data_lookup(req, "null"); nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req)); for (i = 0; i < COUNT; i += ncolumns) { for (j = i; j < MIN(i + ncolumns, 2); j++) { printf("%-*s", field_width, knp[j].name); } printf("\n"); for (j = i; j < MIN(i + ncolumns, 2); j++) { if (tot && interval && kptr_old != NULL) per = (int)((knp[j].value.ui64 - kptr_old[j].value.ui64) * 100 / tot); else if (tot) per = (int)(knp[j].value.ui64 * 100 / tot); else per = 0; (void) sprintf(fixlen, "%" PRIu64 " %d%% ", ((interval && kptr_old != NULL) ? (knp[j].value.ui64 - kptr_old[j].value.ui64) : knp[j].value.ui64), per); printf("%-*s", field_width, fixlen); } printf("\n"); } printf("Version 4: (%" PRIu64 " operations)\n", tot_ops); for (i = 2; i < nreq; i += ncolumns) { for (j = i; j < MIN(i + ncolumns, nreq); j++) { printf("%-*s", field_width, knp[j].name); } printf("\n"); for (j = i; j < MIN(i + ncolumns, nreq); j++) { if (tot_ops && interval && kptr_old != NULL) per = (int)((knp[j].value.ui64 - kptr_old[j].value.ui64) * 100 / tot_ops); else if (tot_ops) per = (int)(knp[j].value.ui64 * 100 / tot_ops); else per = 0; (void) sprintf(fixlen, "%" PRIu64 " %d%% ", ((interval && kptr_old != NULL) ? (knp[j].value.ui64 - kptr_old[j].value.ui64) : knp[j].value.ui64), per); printf("%-*s", field_width, fixlen); } printf("\n"); } if (zflag) { for (i = 0; i < req->ks_ndata; i++) kptr[i].value.ui64 = 0; } if (kptr_old != NULL) kstat_copy(req, req_old, 1); else kstat_copy(req, req_old, 0); }
static void req_print(kstat_t *req, kstat_t *req_old, int ver, int field_width, int zflag) { int i, j, nreq, per, ncolumns; uint64_t tot, old_tot; char fixlen[128]; kstat_named_t *knp; kstat_named_t *kptr; kstat_named_t *knp_old; if (req == NULL) return; if (field_width == 0) return; ncolumns = (MAX_COLUMNS -1)/field_width; knp = kstat_data_lookup(req, "null"); knp_old = KSTAT_NAMED_PTR(req_old); kptr = KSTAT_NAMED_PTR(req); nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req)); tot = 0; old_tot = 0; if (knp_old == NULL) { old_tot = 0; } for (i = 0; i < req->ks_ndata; i++) tot += kptr[i].value.ui64; if (interval && knp_old != NULL) { for (i = 0; i < req_old->ks_ndata; i++) old_tot += knp_old[i].value.ui64; tot -= old_tot; } printf("Version %d: (%" PRIu64 " calls)\n", ver, tot); for (i = 0; i < nreq; i += ncolumns) { for (j = i; j < MIN(i + ncolumns, nreq); j++) { printf("%-*s", field_width, knp[j].name); } printf("\n"); for (j = i; j < MIN(i + ncolumns, nreq); j++) { if (tot && interval && knp_old != NULL) per = (int)((knp[j].value.ui64 - knp_old[j].value.ui64) * 100 / tot); else if (tot) per = (int)(knp[j].value.ui64 * 100 / tot); else per = 0; (void) sprintf(fixlen, "%" PRIu64 " %d%% ", ((interval && knp_old != NULL) ? (knp[j].value.ui64 - knp_old[j].value.ui64) : knp[j].value.ui64), per); printf("%-*s", field_width, fixlen); } printf("\n"); } if (zflag) { for (i = 0; i < req->ks_ndata; i++) knp[i].value.ui64 = 0; } if (knp_old != NULL) kstat_copy(req, req_old, 1); else kstat_copy(req, req_old, 0); }
int getKstat(const char *statname, const char *varname, void *value) { kstat_ctl_t *ksc; kstat_t *ks, *kstat_data; kstat_named_t *d; size_t i, instance; char module_name[64]; int ret; u_longlong_t val; /* The largest value */ void *v; if (value == NULL) { /* Pretty useless but ... */ v = (void *) &val; } else { v = value; } if (kstat_fd == 0) { kstat_fd = kstat_open(); if (kstat_fd == 0) { snmp_log(LOG_ERR, "kstat_open(): failed\n"); } } if ((ksc = kstat_fd) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (statname == NULL || varname == NULL) { ret = -20; goto Return; } /* * First, get "kstat_headers" statistics. It should * contain all available modules. */ if ((ks = kstat_lookup(ksc, "unix", 0, "kstat_headers")) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } kstat_data = ks->ks_data; /* * Now, look for the name of our stat in the headers buf */ for (i = 0; i < ks->ks_ndata; i++) { DEBUGMSGTL(("kernel_sunos5", "module: %s instance: %d name: %s class: %s type: %d flags: %x\n", kstat_data[i].ks_module, kstat_data[i].ks_instance, kstat_data[i].ks_name, kstat_data[i].ks_class, kstat_data[i].ks_type, kstat_data[i].ks_flags)); if (strcmp(statname, kstat_data[i].ks_name) == 0) { strcpy(module_name, kstat_data[i].ks_module); instance = kstat_data[i].ks_instance; break; } } if (i == ks->ks_ndata) { ret = -1; goto Return; /* Not found */ } /* * Get the named statistics */ if ((ks = kstat_lookup(ksc, module_name, instance, statname)) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } /* * This function expects only name/value type of statistics, so if it is * not the case return an error */ if (ks->ks_type != KSTAT_TYPE_NAMED) { ret = -2; goto Return; /* Invalid stat type */ } for (i = 0, d = KSTAT_NAMED_PTR(ks); i < ks->ks_ndata; i++, d++) { DEBUGMSGTL(("kernel_sunos5", "variable: \"%s\" (type %d)\n", d->name, d->data_type)); if (strcmp(d->name, varname) == 0) { switch (d->data_type) { case KSTAT_DATA_CHAR: *(char *)v = (int)d->value.c; DEBUGMSGTL(("kernel_sunos5", "value: %d\n", (int)d->value.c)); break; #ifdef KSTAT_DATA_INT32 /* Solaris 2.6 and up */ case KSTAT_DATA_INT32: *(Counter *)v = d->value.i32; DEBUGMSGTL(("kernel_sunos5", "value: %d\n", d->value.i32)); break; case KSTAT_DATA_UINT32: *(Counter *)v = d->value.ui32; DEBUGMSGTL(("kernel_sunos5", "value: %u\n", d->value.ui32)); break; case KSTAT_DATA_INT64: *(int64_t *)v = d->value.i64; DEBUGMSGTL(("kernel_sunos5", "value: %ld\n", d->value.i64)); break; case KSTAT_DATA_UINT64: *(uint64_t *)v = d->value.ui64; DEBUGMSGTL(("kernel_sunos5", "value: %lu\n", d->value.ui64)); break; #else case KSTAT_DATA_LONG: *(Counter *)v = d->value.l; DEBUGMSGTL(("kernel_sunos5", "value: %ld\n", d->value.l)); break; case KSTAT_DATA_ULONG: *(Counter *)v = d->value.ul; DEBUGMSGTL(("kernel_sunos5", "value: %lu\n", d->value.ul)); break; case KSTAT_DATA_LONGLONG: *(Counter *)v = d->value.ll; DEBUGMSGTL(("kernel_sunos5", "value: %lld\n", (long)d->value.ll)); break; case KSTAT_DATA_ULONGLONG: *(Counter *)v = d->value.ull; DEBUGMSGTL(("kernel_sunos5", "value: %llu\n", (unsigned long)d->value.ull)); break; #endif case KSTAT_DATA_FLOAT: *(float *)v = d->value.f; DEBUGMSGTL(("kernel_sunos5", "value: %f\n", d->value.f)); break; case KSTAT_DATA_DOUBLE: *(double *)v = d->value.d; DEBUGMSGTL(("kernel_sunos5", "value: %f\n", d->value.d)); break; default: DEBUGMSGTL(("kernel_sunos5", "UNKNOWN TYPE %d (stat \"%s\" var \"%s\")\n", d->data_type, statname, varname)); ret = -3; goto Return; /* Invalid data type */ } ret = 0; /* Success */ goto Return; } } ret = -4; /* Name not found */ Return: return ret; }
// It prints all the statistics related to a particular kstat // If -l,-p option is used then it prints in different form // using the prefix provided as an argument to the function void kstat_data_look(kstat_t *ksp,char* prefix,int opt) { int i, size; char *namep; char *datap; kstat_named_t* knp; switch (ksp->ks_type) { case KSTAT_TYPE_NAMED: size = sizeof (kstat_named_t); namep = KSTAT_NAMED_PTR(ksp)->name; break; case KSTAT_TYPE_TIMER: size = sizeof (kstat_timer_t); namep = KSTAT_TIMER_PTR(ksp)->name; break; default: errno = EINVAL; return; } datap = ksp->ks_data; for (i = 0; i < ksp->ks_ndata; i++) { knp = kstat_data_lookup(ksp,namep); if(strcmp(prefix,"\0") == 0) { if(knp->data_type == KSTAT_DATA_CHAR) printf(" %-30.30s %-.30s\n",namep,knp->value.c); else if(knp->data_type == KSTAT_DATA_INT32) printf(" %-30.30s %d\n",namep,knp->value.i32); else if(knp->data_type == KSTAT_DATA_UINT32) printf(" %-30.30s %d\n",namep,knp->value.ui32); else if(knp->data_type == KSTAT_DATA_INT64) printf(" %-30.30s %d\n",namep,knp->value.i64); else if(knp->data_type == KSTAT_DATA_UINT64) printf(" %-30.30s %d\n",namep,knp->value.ui64); else printf(" %-30.30s %s\n",namep,knp->value); } else { printf("%s",prefix); if(opt == 1) printf("%s\n",namep); if(opt == 2) { if(knp->data_type == KSTAT_DATA_CHAR) printf("%s\t%s\n",namep,knp->value.c); else if(knp->data_type == KSTAT_DATA_INT32) printf("%s\t%d\n",namep,knp->value.i32); else if(knp->data_type == KSTAT_DATA_UINT32) printf("%s\t%d\n",namep,knp->value.ui32); else if(knp->data_type == KSTAT_DATA_INT64) printf("%s\t%d\n",namep,knp->value.i64); else if(knp->data_type == KSTAT_DATA_UINT64) printf("%s\t%d\n",namep,knp->value.ui64); else printf("%s\t%s\n",namep,knp->value); } } namep += size; datap += size; } errno = ENOENT; return; }
int getKstatString(const char *statname, const char *varname, char *value, size_t value_len) { kstat_ctl_t *ksc; kstat_t *ks, *kstat_data; kstat_named_t *d; size_t i, instance; char module_name[64]; int ret; if (kstat_fd == 0) { kstat_fd = kstat_open(); if (kstat_fd == 0) { snmp_log_perror("kstat_open"); } } if ((ksc = kstat_fd) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (statname == NULL || varname == NULL) { ret = -20; goto Return; } /* * First, get "kstat_headers" statistics. It should * contain all available modules. */ if ((ks = kstat_lookup(ksc, "unix", 0, "kstat_headers")) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } kstat_data = ks->ks_data; /* * Now, look for the name of our stat in the headers buf */ for (i = 0; i < ks->ks_ndata; i++) { DEBUGMSGTL(("kernel_sunos5", "module: %s instance: %d name: %s class: %s type: %d flags: %x\n", kstat_data[i].ks_module, kstat_data[i].ks_instance, kstat_data[i].ks_name, kstat_data[i].ks_class, kstat_data[i].ks_type, kstat_data[i].ks_flags)); if (strcmp(statname, kstat_data[i].ks_name) == 0) { strcpy(module_name, kstat_data[i].ks_module); instance = kstat_data[i].ks_instance; break; } } if (i == ks->ks_ndata) { ret = -1; goto Return; /* Not found */ } /* * Get the named statistics */ if ((ks = kstat_lookup(ksc, module_name, instance, statname)) == NULL) { ret = -10; goto Return; /* kstat errors */ } if (kstat_read(ksc, ks, NULL) <= 0) { ret = -10; goto Return; /* kstat errors */ } /* * This function expects only name/value type of statistics, so if it is * not the case return an error */ if (ks->ks_type != KSTAT_TYPE_NAMED) { ret = -2; goto Return; /* Invalid stat type */ } for (i = 0, d = KSTAT_NAMED_PTR(ks); i < ks->ks_ndata; i++, d++) { DEBUGMSGTL(("kernel_sunos5", "variable: \"%s\" (type %d)\n", d->name, d->data_type)); if (strcmp(d->name, varname) == 0) { switch (d->data_type) { case KSTAT_DATA_CHAR: value[value_len-1] = '\0'; strncpy(value, d->value.c, value_len-1); DEBUGMSGTL(("kernel_sunos5", "value: %s\n", d->value.c)); break; default: DEBUGMSGTL(("kernel_sunos5", "NONSTRING TYPE %d (stat \"%s\" var \"%s\")\n", d->data_type, statname, varname)); ret = -3; goto Return; /* Invalid data type */ } ret = 0; /* Success */ goto Return; } } ret = -4; /* Name not found */ Return: return ret; }