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);
}