Print this page
check return from clock_gettime.
fix cstyle
codereview and testing fixes.
6558 kstat: desire type for timestamps

*** 22,31 **** --- 22,32 ---- /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 David Hoeppner. All rights reserved. * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright 2016 Garrett D'Amore */ /* * Display kernel statistics *
*** 37,46 **** --- 38,53 ---- * * Flags added: * -C similar to the -p option but value is separated by a colon * -h display help * -j json format + * -H b display hrtime as seconds since boot + * -H d display hrtime as date + * -H u display hrtime as UNIX seconds (since epoch) + * -H I display hrtime as ISO-8601 local time + * -H Z display hrtime as ISO-8601 UTC + * -H n display hrtime as nanoseconds (since epoch) */ #include <assert.h> #include <ctype.h> #include <errno.h>
*** 66,75 **** --- 73,83 ---- char *cmdname = "kstat"; /* Name of this command */ int caught_cont = 0; /* Have caught a SIGCONT */ static uint_t g_timestamp_fmt = NODATE; + static uint_t g_hrtime_fmt = KS_HRFMT_DEFAULT; /* Helper flag - header was printed already? */ static boolean_t g_headerflg; /* Saved command line options */
*** 85,94 **** --- 93,104 ---- /* Sorted list of kstat instances */ static list_t instances_list; static list_t selector_list; + static hrtime_t hrtime_origin; + int main(int argc, char **argv) { ks_selector_t *nselector; ks_selector_t *uselector;
*** 122,132 **** nselector = new_selector(); /* * Parse named command line arguments. */ ! while ((c = getopt(argc, argv, "h?CqjlpT:m:i:n:s:c:")) != EOF) switch (c) { case 'h': case '?': usage(); exit(0); --- 132,142 ---- nselector = new_selector(); /* * Parse named command line arguments. */ ! while ((c = getopt(argc, argv, "h?CqjlpT:m:i:n:s:c:H:")) != EOF) switch (c) { case 'h': case '?': usage(); exit(0);
*** 145,154 **** --- 155,167 ---- break; case 'p': g_pflg = B_TRUE; break; case 'T': + if (strlen(optarg) != 1) { + errflg = B_TRUE; + } switch (*optarg) { case 'd': g_timestamp_fmt = DDATE; break; case 'u':
*** 180,200 **** --- 193,249 ---- break; case 'c': g_ks_class.pstr = (char *)ks_safe_strdup(optarg); break; + case 'H': + switch (*optarg) { + case 'o': + case 'b': + case 'n': + case 'I': + case 'Z': + case 'd': + case 'u': + if (strlen(optarg) != 1) { + errflg = B_TRUE; + } + g_hrtime_fmt = *optarg; + break; default: errflg = B_TRUE; break; } + break; + default: + errflg = B_TRUE; + break; + } if (g_qflg && (g_jflg || g_pflg)) { (void) fprintf(stderr, gettext( "-q and -lpj are mutually exclusive\n")); errflg = B_TRUE; } + switch (g_hrtime_fmt) { + case KS_HRFMT_DEFAULT: + case KS_HRFMT_BOOT: + break; + default: { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { + perror("clock_gettime(CLOCK_REALTIME)"); + exit(3); + } + hrtime_origin = ts.tv_sec; + hrtime_origin *= 1000000000; + hrtime_origin += ts.tv_nsec; + hrtime_origin -= gethrtime(); + } + } + if (errflg) { usage(); exit(2); }
*** 350,363 **** static void usage(void) { (void) fprintf(stderr, gettext( "Usage:\n" ! "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n" " [ -m module ] [ -i instance ] [ -n name ] [ -s statistic ]\n" " [ interval [ count ] ]\n" ! "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n" " [ module[:instance[:name[:statistic]]] ... ]\n" " [ interval [ count ] ]\n")); } /* --- 399,412 ---- static void usage(void) { (void) fprintf(stderr, gettext( "Usage:\n" ! "kstat [ -Cjlpq ] [ -T d|u ] [ -H d|n|u|I|Z ] [ -c class ]\n" " [ -m module ] [ -i instance ] [ -n name ] [ -s statistic ]\n" " [ interval [ count ] ]\n" ! "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ] [ -H d|n|u|I|Z ]\n" " [ module[:instance[:name[:statistic]]] ... ]\n" " [ interval [ count ] ]\n")); } /*
*** 706,715 **** --- 755,768 ---- * Print the value of a name-value pair. */ static void ks_value_print(ks_nvpair_t *nvpair) { + char dstr[64]; + char zstr[8]; + time_t t; + switch (nvpair->data_type) { case KSTAT_DATA_CHAR: (void) fprintf(stdout, "%s", nvpair->value.c); break; case KSTAT_DATA_INT32:
*** 725,742 **** (void) fprintf(stdout, "%llu", nvpair->value.ui64); break; case KSTAT_DATA_STRING: (void) fprintf(stdout, "%s", KSTAT_NAMED_STR_PTR(nvpair)); break; ! case KSTAT_DATA_HRTIME: if (nvpair->value.ui64 == 0) (void) fprintf(stdout, "0"); else (void) fprintf(stdout, "%.9f", nvpair->value.ui64 / 1000000000.0); break; default: assert(B_FALSE); } } /* --- 778,836 ---- (void) fprintf(stdout, "%llu", nvpair->value.ui64); break; case KSTAT_DATA_STRING: (void) fprintf(stdout, "%s", KSTAT_NAMED_STR_PTR(nvpair)); break; ! case KSTAT_DATA_TIME: ! switch (g_hrtime_fmt) { ! case KS_HRFMT_UNIX: ! (void) fprintf(stdout, "%.9f", ! (nvpair->value.t + hrtime_origin) / 1000000000.0); ! break; ! case KS_HRFMT_NANO: ! (void) fprintf(stdout, "%llu", ! (nvpair->value.t + hrtime_origin)); ! break; ! case KS_HRFMT_DATE: ! t = (time_t) ! ((nvpair->value.t + hrtime_origin) / 1000000000); ! (void) strftime(dstr, ! sizeof (dstr), "%+", localtime(&t)); ! (void) fprintf(stdout, "%s", dstr); ! break; ! case KS_HRFMT_ZISO: ! t = (time_t) ! ((nvpair->value.t + hrtime_origin) / 1000000000); ! (void) strftime(dstr, sizeof (dstr), "%FT%T", ! gmtime(&t)); ! (void) fprintf(stdout, "%s.%06uZ", dstr, ! (unsigned)(nvpair->value.t % 1000000000)/1000); ! break; ! case KS_HRFMT_ISO: ! t = (time_t) ! ((nvpair->value.t + hrtime_origin) / 1000000000); ! (void) strftime(dstr, sizeof (dstr), "%FT%T", ! localtime(&t)); ! (void) strftime(zstr, sizeof (zstr), "%z", ! localtime(&t)); ! (void) fprintf(stdout, "%s.%06u%s", dstr, ! (unsigned)(nvpair->value.t % 1000000000)/1000, ! zstr); ! break; ! case KS_HRFMT_DEFAULT: ! case KS_HRFMT_BOOT: if (nvpair->value.ui64 == 0) (void) fprintf(stdout, "0"); else (void) fprintf(stdout, "%.9f", nvpair->value.ui64 / 1000000000.0); break; default: + abort(); + } + break; + default: assert(B_FALSE); } } /*
*** 796,805 **** --- 890,911 ---- (void) fprintf(stdout, KS_JFMT, nvpair->name); if (nvpair->data_type == KSTAT_DATA_STRING) { (void) putchar('\"'); ks_value_print(nvpair); (void) putchar('\"'); + } else if (nvpair->data_type == KSTAT_DATA_TIME) { + switch (g_hrtime_fmt) { + case KS_HRFMT_ISO: + case KS_HRFMT_ZISO: + case KS_HRFMT_DATE: + (void) putchar('\"'); + ks_value_print(nvpair); + (void) putchar('\"'); + break; + default: + ks_value_print(nvpair); + } } else { ks_value_print(nvpair); } if (nvpair != list_tail(&ksi->ks_nvlist)) (void) putchar(',');
*** 1386,1413 **** 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(ksi, knp->name, - (ks_value_t *)&knp->value, KSTAT_DATA_CHAR); - break; case KSTAT_DATA_INT32: - nvpair_insert(ksi, knp->name, - (ks_value_t *)&knp->value, KSTAT_DATA_INT32); - break; case KSTAT_DATA_UINT32: - nvpair_insert(ksi, knp->name, - (ks_value_t *)&knp->value, KSTAT_DATA_UINT32); - break; case KSTAT_DATA_INT64: - nvpair_insert(ksi, knp->name, - (ks_value_t *)&knp->value, KSTAT_DATA_INT64); - break; case KSTAT_DATA_UINT64: nvpair_insert(ksi, knp->name, ! (ks_value_t *)&knp->value, KSTAT_DATA_UINT64); break; case KSTAT_DATA_STRING: SAVE_STRING_X(ksi, knp->name, KSTAT_NAMED_STR_PTR(knp)); break; default: --- 1492,1508 ---- int n; for (n = kp->ks_ndata, knp = KSTAT_NAMED_PTR(kp); n > 0; n--, knp++) { switch (knp->data_type) { case KSTAT_DATA_CHAR: case KSTAT_DATA_INT32: case KSTAT_DATA_UINT32: case KSTAT_DATA_INT64: case KSTAT_DATA_UINT64: + case KSTAT_DATA_TIME: nvpair_insert(ksi, knp->name, ! (ks_value_t *)&knp->value, knp->data_type); break; case KSTAT_DATA_STRING: SAVE_STRING_X(ksi, knp->name, KSTAT_NAMED_STR_PTR(knp)); break; default:
*** 1436,1450 **** SAVE_UINT64(ksi, ksio, nread); SAVE_UINT64(ksi, ksio, nwritten); SAVE_UINT32(ksi, ksio, reads); SAVE_UINT32(ksi, ksio, writes); ! SAVE_HRTIME(ksi, ksio, wtime); ! SAVE_HRTIME(ksi, ksio, wlentime); SAVE_HRTIME(ksi, ksio, wlastupdate); ! SAVE_HRTIME(ksi, ksio, rtime); ! SAVE_HRTIME(ksi, ksio, rlentime); SAVE_HRTIME(ksi, ksio, rlastupdate); SAVE_UINT32(ksi, ksio, wcnt); SAVE_UINT32(ksi, ksio, rcnt); } --- 1531,1545 ---- SAVE_UINT64(ksi, ksio, nread); SAVE_UINT64(ksi, ksio, nwritten); SAVE_UINT32(ksi, ksio, reads); SAVE_UINT32(ksi, ksio, writes); ! SAVE_UINT64(ksi, ksio, wtime); ! SAVE_UINT64(ksi, ksio, wlentime); SAVE_HRTIME(ksi, ksio, wlastupdate); ! SAVE_UINT64(ksi, ksio, rtime); ! SAVE_UINT64(ksi, ksio, rlentime); SAVE_HRTIME(ksi, ksio, rlastupdate); SAVE_UINT32(ksi, ksio, wcnt); SAVE_UINT32(ksi, ksio, rcnt); }
*** 1453,1463 **** { kstat_timer_t *ktimer = KSTAT_TIMER_PTR(kp); SAVE_STRING(ksi, ktimer, name); SAVE_UINT64(ksi, ktimer, num_events); ! SAVE_HRTIME(ksi, ktimer, elapsed_time); ! SAVE_HRTIME(ksi, ktimer, min_time); ! SAVE_HRTIME(ksi, ktimer, max_time); SAVE_HRTIME(ksi, ktimer, start_time); SAVE_HRTIME(ksi, ktimer, stop_time); } --- 1548,1558 ---- { kstat_timer_t *ktimer = KSTAT_TIMER_PTR(kp); SAVE_STRING(ksi, ktimer, name); SAVE_UINT64(ksi, ktimer, num_events); ! SAVE_UINT64(ksi, ktimer, elapsed_time); ! SAVE_UINT64(ksi, ktimer, min_time); ! SAVE_UINT64(ksi, ktimer, max_time); SAVE_HRTIME(ksi, ktimer, start_time); SAVE_HRTIME(ksi, ktimer, stop_time); }