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