Print this page
3623 kstat must accept partial stat specification


  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013 David Hoeppner. All rights reserved.
  25  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 /*
  29  * Display kernel statistics
  30  *
  31  * This is a reimplementation of the perl kstat command originally found
  32  * under usr/src/cmd/kstat/kstat.pl
  33  *
  34  * Incompatibilities:
  35  *      - perl regular expressions replaced with extended REs bracketed by '/'
  36  *      - options checking is stricter
  37  *
  38  * Flags added:
  39  *      -C      similar to the -p option but value is separated by a colon
  40  *      -h      display help
  41  *      -j      json format
  42  */
  43 
  44 #include <assert.h>
  45 #include <ctype.h>
  46 #include <errno.h>
  47 #include <kstat.h>
  48 #include <langinfo.h>
  49 #include <libgen.h>
  50 #include <limits.h>
  51 #include <locale.h>
  52 #include <signal.h>
  53 #include <stddef.h>
  54 #include <stdio.h>
  55 #include <stdlib.h>
  56 #include <string.h>


 238                                                     (char *)ks_safe_strdup(q);
 239                                                 break;
 240                                         case 2:
 241                                                 uselector->ks_instance.pstr =
 242                                                     (char *)ks_safe_strdup(q);
 243                                                 break;
 244                                         case 3:
 245                                                 uselector->ks_name.pstr =
 246                                                     (char *)ks_safe_strdup(q);
 247                                                 break;
 248                                         case 4:
 249                                                 uselector->ks_statistic.pstr =
 250                                                     (char *)ks_safe_strdup(q);
 251                                                 break;
 252                                         default:
 253                                                 assert(B_FALSE);
 254                                         }
 255                                 }
 256                         }
 257 
 258                         if (m < 4) {
 259                                 free(uselector);
 260                                 usage();
 261                                 exit(2);
 262                         }
 263 
 264                         uselflg = B_TRUE;
 265                         list_insert_tail(&selector_list, uselector);
 266                 } else {
 267                         if (tmp < 1) {
 268                                 if (n == 0) {
 269                                         (void) fprintf(stderr, gettext(
 270                                             "Interval must be an "
 271                                             "integer >= 1"));
 272                                 } else if (n == 1) {
 273                                         (void) fprintf(stderr, gettext(
 274                                             "Count must be an integer >= 1"));
 275                                 }
 276                                 usage();
 277                                 exit(2);
 278                         } else {
 279                                 if (n == 0) {
 280                                         interval = tmp;
 281                                         count = -1;
 282                                 } else if (n == 1) {
 283                                         count = tmp;
 284                                 } else {
 285                                         usage();
 286                                         exit(2);
 287                                 }
 288                         }
 289                         n++;
 290                 }
 291                 argv++;
 292         }
 293 
 294         /*
 295          * Check if we founded a named selector on the cmdline.
 296          */
 297         if (uselflg) {
 298                 if (nselflg) {
 299                         (void) fprintf(stderr, gettext(
 300                             "module:instance:name:statistic and "
 301                             "-m -i -n -s are mutually exclusive"));
 302                         usage();
 303                         exit(2);
 304                 } else {
 305                         free(nselector);
 306                 }
 307         } else {
 308                 list_insert_tail(&selector_list, nselector);
 309         }
 310 
 311         assert(!list_is_empty(&selector_list));
 312 
 313         list_create(&instances_list, sizeof (ks_instance_t),
 314             offsetof(ks_instance_t, ks_next));
 315 
 316         while ((kc = kstat_open()) == NULL) {
 317                 if (errno == EAGAIN) {
 318                         (void) poll(NULL, 0, 200);
 319                 } else {
 320                         perror("kstat_open");


 345                 }
 346         }
 347 
 348         (void) kstat_close(kc);
 349 
 350         return (g_matched);
 351 }
 352 
 353 /*
 354  * Print usage.
 355  */
 356 static void
 357 usage(void)
 358 {
 359         (void) fprintf(stderr, gettext(
 360             "Usage:\n"
 361             "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
 362             "      [ -m module ] [ -i instance ] [ -n name ] [ -s statistic ]\n"
 363             "      [ interval [ count ] ]\n"
 364             "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
 365             "      [ module:instance:name:statistic ... ]\n"
 366             "      [ interval [ count ] ]\n"));
 367 }
 368 
 369 /*
 370  * Sort compare function.
 371  */
 372 static int
 373 compare_instances(ks_instance_t *l_arg, ks_instance_t *r_arg)
 374 {
 375         int     rval;
 376 
 377         rval = strcasecmp(l_arg->ks_module, r_arg->ks_module);
 378         if (rval == 0) {
 379                 if (l_arg->ks_instance == r_arg->ks_instance) {
 380                         return (strcasecmp(l_arg->ks_name, r_arg->ks_name));
 381                 } else if (l_arg->ks_instance < r_arg->ks_instance) {
 382                         return (-1);
 383                 } else {
 384                         return (1);
 385                 }




  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013 David Hoeppner. All rights reserved.
  25  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 /*
  29  * Display kernel statistics
  30  *
  31  * This is a reimplementation of the perl kstat command originally found
  32  * under usr/src/cmd/kstat/kstat.pl
  33  *
  34  * Incompatibilities:
  35  *      - perl regular expressions replaced with extended REs bracketed by '/'

  36  *
  37  * Flags added:
  38  *      -C      similar to the -p option but value is separated by a colon
  39  *      -h      display help
  40  *      -j      json format
  41  */
  42 
  43 #include <assert.h>
  44 #include <ctype.h>
  45 #include <errno.h>
  46 #include <kstat.h>
  47 #include <langinfo.h>
  48 #include <libgen.h>
  49 #include <limits.h>
  50 #include <locale.h>
  51 #include <signal.h>
  52 #include <stddef.h>
  53 #include <stdio.h>
  54 #include <stdlib.h>
  55 #include <string.h>


 237                                                     (char *)ks_safe_strdup(q);
 238                                                 break;
 239                                         case 2:
 240                                                 uselector->ks_instance.pstr =
 241                                                     (char *)ks_safe_strdup(q);
 242                                                 break;
 243                                         case 3:
 244                                                 uselector->ks_name.pstr =
 245                                                     (char *)ks_safe_strdup(q);
 246                                                 break;
 247                                         case 4:
 248                                                 uselector->ks_statistic.pstr =
 249                                                     (char *)ks_safe_strdup(q);
 250                                                 break;
 251                                         default:
 252                                                 assert(B_FALSE);
 253                                         }
 254                                 }
 255                         }
 256 






 257                         uselflg = B_TRUE;
 258                         list_insert_tail(&selector_list, uselector);
 259                 } else {
 260                         if (tmp < 1) {
 261                                 if (n == 0) {
 262                                         (void) fprintf(stderr, gettext(
 263                                             "Interval must be an "
 264                                             "integer >= 1"));
 265                                 } else if (n == 1) {
 266                                         (void) fprintf(stderr, gettext(
 267                                             "Count must be an integer >= 1"));
 268                                 }
 269                                 usage();
 270                                 exit(2);
 271                         } else {
 272                                 if (n == 0) {
 273                                         interval = tmp;
 274                                         count = -1;
 275                                 } else if (n == 1) {
 276                                         count = tmp;
 277                                 } else {
 278                                         usage();
 279                                         exit(2);
 280                                 }
 281                         }
 282                         n++;
 283                 }
 284                 argv++;
 285         }
 286 
 287         /*
 288          * Check if we founded a named selector on the cmdline.
 289          */
 290         if (uselflg) {
 291                 if (nselflg) {
 292                         (void) fprintf(stderr, gettext(
 293                             "[module[:instance[:name[:statistic]]]] and "
 294                             "-m -i -n -s are mutually exclusive"));
 295                         usage();
 296                         exit(2);
 297                 } else {
 298                         free(nselector);
 299                 }
 300         } else {
 301                 list_insert_tail(&selector_list, nselector);
 302         }
 303 
 304         assert(!list_is_empty(&selector_list));
 305 
 306         list_create(&instances_list, sizeof (ks_instance_t),
 307             offsetof(ks_instance_t, ks_next));
 308 
 309         while ((kc = kstat_open()) == NULL) {
 310                 if (errno == EAGAIN) {
 311                         (void) poll(NULL, 0, 200);
 312                 } else {
 313                         perror("kstat_open");


 338                 }
 339         }
 340 
 341         (void) kstat_close(kc);
 342 
 343         return (g_matched);
 344 }
 345 
 346 /*
 347  * Print usage.
 348  */
 349 static void
 350 usage(void)
 351 {
 352         (void) fprintf(stderr, gettext(
 353             "Usage:\n"
 354             "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
 355             "      [ -m module ] [ -i instance ] [ -n name ] [ -s statistic ]\n"
 356             "      [ interval [ count ] ]\n"
 357             "kstat [ -Cjlpq ] [ -T d|u ] [ -c class ]\n"
 358             "      [ module[:instance[:name[:statistic]]] ... ]\n"
 359             "      [ interval [ count ] ]\n"));
 360 }
 361 
 362 /*
 363  * Sort compare function.
 364  */
 365 static int
 366 compare_instances(ks_instance_t *l_arg, ks_instance_t *r_arg)
 367 {
 368         int     rval;
 369 
 370         rval = strcasecmp(l_arg->ks_module, r_arg->ks_module);
 371         if (rval == 0) {
 372                 if (l_arg->ks_instance == r_arg->ks_instance) {
 373                         return (strcasecmp(l_arg->ks_name, r_arg->ks_name));
 374                 } else if (l_arg->ks_instance < r_arg->ks_instance) {
 375                         return (-1);
 376                 } else {
 377                         return (1);
 378                 }