| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: vmstat.c,v 1.245 2021/04/01 06:23:14 simonb Exp $ */ | | 1 | /* $NetBSD: vmstat.c,v 1.246 2021/04/02 06:28:55 simonb Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1998, 2000, 2001, 2007, 2019, 2020 | | 4 | * Copyright (c) 1998, 2000, 2001, 2007, 2019, 2020 |
5 | * The NetBSD Foundation, Inc. | | 5 | * The NetBSD Foundation, Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation by: | | 8 | * This code is derived from software contributed to The NetBSD Foundation by: |
9 | * - Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | | 9 | * - Jason R. Thorpe of the Numerical Aerospace Simulation Facility, |
10 | * NASA Ames Research Center. | | 10 | * NASA Ames Research Center. |
11 | * - Simon Burge and Luke Mewburn of Wasabi Systems, Inc. | | 11 | * - Simon Burge and Luke Mewburn of Wasabi Systems, Inc. |
12 | * | | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | | 13 | * Redistribution and use in source and binary forms, with or without |
14 | * modification, are permitted provided that the following conditions | | 14 | * modification, are permitted provided that the following conditions |
| @@ -61,27 +61,27 @@ | | | @@ -61,27 +61,27 @@ |
61 | * SUCH DAMAGE. | | 61 | * SUCH DAMAGE. |
62 | */ | | 62 | */ |
63 | | | 63 | |
64 | #include <sys/cdefs.h> | | 64 | #include <sys/cdefs.h> |
65 | #ifndef lint | | 65 | #ifndef lint |
66 | __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\ | | 66 | __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1991, 1993\ |
67 | The Regents of the University of California. All rights reserved."); | | 67 | The Regents of the University of California. All rights reserved."); |
68 | #endif /* not lint */ | | 68 | #endif /* not lint */ |
69 | | | 69 | |
70 | #ifndef lint | | 70 | #ifndef lint |
71 | #if 0 | | 71 | #if 0 |
72 | static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; | | 72 | static char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 3/1/95"; |
73 | #else | | 73 | #else |
74 | __RCSID("$NetBSD: vmstat.c,v 1.245 2021/04/01 06:23:14 simonb Exp $"); | | 74 | __RCSID("$NetBSD: vmstat.c,v 1.246 2021/04/02 06:28:55 simonb Exp $"); |
75 | #endif | | 75 | #endif |
76 | #endif /* not lint */ | | 76 | #endif /* not lint */ |
77 | | | 77 | |
78 | #define __POOL_EXPOSE | | 78 | #define __POOL_EXPOSE |
79 | #define __NAMECACHE_PRIVATE | | 79 | #define __NAMECACHE_PRIVATE |
80 | | | 80 | |
81 | #include <sys/param.h> | | 81 | #include <sys/param.h> |
82 | #include <sys/types.h> | | 82 | #include <sys/types.h> |
83 | #include <sys/mount.h> | | 83 | #include <sys/mount.h> |
84 | #include <sys/uio.h> | | 84 | #include <sys/uio.h> |
85 | | | 85 | |
86 | #include <sys/buf.h> | | 86 | #include <sys/buf.h> |
87 | #include <sys/evcnt.h> | | 87 | #include <sys/evcnt.h> |
| @@ -318,39 +318,37 @@ void hist_dodump_sysctl(int[], unsigned | | | @@ -318,39 +318,37 @@ void hist_dodump_sysctl(int[], unsigned |
318 | | | 318 | |
319 | char **choosedrives(char **); | | 319 | char **choosedrives(char **); |
320 | | | 320 | |
321 | /* Namelist and memory file names. */ | | 321 | /* Namelist and memory file names. */ |
322 | char *nlistf, *memf; | | 322 | char *nlistf, *memf; |
323 | | | 323 | |
324 | /* allow old usage [vmstat 1] */ | | 324 | /* allow old usage [vmstat 1] */ |
325 | #define BACKWARD_COMPATIBILITY | | 325 | #define BACKWARD_COMPATIBILITY |
326 | | | 326 | |
327 | static const int clockrate_mib[] = { CTL_KERN, KERN_CLOCKRATE }; | | 327 | static const int clockrate_mib[] = { CTL_KERN, KERN_CLOCKRATE }; |
328 | static const int vmmeter_mib[] = { CTL_VM, VM_METER }; | | 328 | static const int vmmeter_mib[] = { CTL_VM, VM_METER }; |
329 | static const int uvmexp2_mib[] = { CTL_VM, VM_UVMEXP2 }; | | 329 | static const int uvmexp2_mib[] = { CTL_VM, VM_UVMEXP2 }; |
330 | static const int boottime_mib[] = { CTL_KERN, KERN_BOOTTIME }; | | 330 | static const int boottime_mib[] = { CTL_KERN, KERN_BOOTTIME }; |
331 | static char kvm_errbuf[_POSIX2_LINE_MAX]; | | | |
332 | | | 331 | |
333 | int | | 332 | int |
334 | main(int argc, char *argv[]) | | 333 | main(int argc, char *argv[]) |
335 | { | | 334 | { |
336 | int c, todo, verbose, wide; | | 335 | int c, todo, verbose, wide; |
337 | struct timespec interval; | | 336 | struct timespec interval; |
338 | int reps; | | 337 | int reps; |
339 | gid_t egid = getegid(); | | | |
340 | const char *histname, *hashname; | | 338 | const char *histname, *hashname; |
| | | 339 | char errbuf[_POSIX2_LINE_MAX]; |
341 | | | 340 | |
342 | histname = hashname = NULL; | | 341 | histname = hashname = NULL; |
343 | (void)setegid(getgid()); | | | |
344 | memf = nlistf = NULL; | | 342 | memf = nlistf = NULL; |
345 | reps = todo = verbose = wide = 0; | | 343 | reps = todo = verbose = wide = 0; |
346 | interval.tv_sec = 0; | | 344 | interval.tv_sec = 0; |
347 | interval.tv_nsec = 0; | | 345 | interval.tv_nsec = 0; |
348 | while ((c = getopt(argc, argv, "Cc:efh:HilLM:mN:stu:UvWw:")) != -1) { | | 346 | while ((c = getopt(argc, argv, "Cc:efh:HilLM:mN:stu:UvWw:")) != -1) { |
349 | switch (c) { | | 347 | switch (c) { |
350 | case 'c': | | 348 | case 'c': |
351 | reps = atoi(optarg); | | 349 | reps = atoi(optarg); |
352 | break; | | 350 | break; |
353 | case 'C': | | 351 | case 'C': |
354 | todo |= POOLCACHESTAT; | | 352 | todo |= POOLCACHESTAT; |
355 | break; | | 353 | break; |
356 | case 'e': | | 354 | case 'e': |
| @@ -405,79 +403,63 @@ main(int argc, char *argv[]) | | | @@ -405,79 +403,63 @@ main(int argc, char *argv[]) |
405 | interval.tv_sec = atol(optarg); | | 403 | interval.tv_sec = atol(optarg); |
406 | break; | | 404 | break; |
407 | case '?': | | 405 | case '?': |
408 | default: | | 406 | default: |
409 | usage(); | | 407 | usage(); |
410 | } | | 408 | } |
411 | } | | 409 | } |
412 | argc -= optind; | | 410 | argc -= optind; |
413 | argv += optind; | | 411 | argv += optind; |
414 | | | 412 | |
415 | if (todo == 0) | | 413 | if (todo == 0) |
416 | todo = VMSTAT; | | 414 | todo = VMSTAT; |
417 | | | 415 | |
418 | /* | | 416 | if (memf == NULL) { |
419 | * Discard setgid privileges. If not the running kernel, we toss | | 417 | kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); |
420 | * them away totally so that bad guys can't print interesting stuff | | 418 | } else { |
421 | * from kernel memory, otherwise switch back to kmem for the | | 419 | kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); |
422 | * duration of the kvm_openfiles() call. | | 420 | getnlist(todo); |
423 | */ | | | |
424 | if (nlistf != NULL || memf != NULL) | | | |
425 | (void)setgid(getgid()); | | | |
426 | else | | | |
427 | (void)setegid(egid); | | | |
428 | | | | |
429 | kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, kvm_errbuf); | | | |
430 | if (kd == NULL) { | | | |
431 | if (nlistf != NULL || memf != NULL) { | | | |
432 | errx(1, "kvm_openfiles: %s", kvm_errbuf); | | | |
433 | } | | | |
434 | } | | 421 | } |
435 | | | 422 | |
436 | if (nlistf == NULL && memf == NULL) | | 423 | if (kd == NULL) |
437 | (void)setgid(getgid()); | | 424 | errx(EXIT_FAILURE, "%s", errbuf); |
438 | | | | |
439 | | | 425 | |
440 | if (todo & VMSTAT) { | | 426 | if (todo & VMSTAT) { |
441 | struct winsize winsize; | | 427 | struct winsize winsize; |
442 | | | 428 | |
443 | (void)drvinit(0);/* Initialize disk stats, no disks selected. */ | | 429 | (void)drvinit(0);/* Initialize disk stats, no disks selected. */ |
444 | | | 430 | |
445 | (void)setgid(getgid()); /* don't need privs anymore */ | | | |
446 | | | | |
447 | argv = choosedrives(argv); /* Select disks. */ | | 431 | argv = choosedrives(argv); /* Select disks. */ |
448 | winsize.ws_row = 0; | | 432 | winsize.ws_row = 0; |
449 | (void)ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); | | 433 | (void)ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); |
450 | if (winsize.ws_row > 0) | | 434 | if (winsize.ws_row > 0) |
451 | winlines = winsize.ws_row; | | 435 | winlines = winsize.ws_row; |
452 | | | 436 | |
453 | } | | 437 | } |
454 | | | 438 | |
455 | #ifdef BACKWARD_COMPATIBILITY | | 439 | #ifdef BACKWARD_COMPATIBILITY |
456 | if (*argv) { | | 440 | if (*argv) { |
457 | interval.tv_sec = atol(*argv); | | 441 | interval.tv_sec = atol(*argv); |
458 | if (*++argv) | | 442 | if (*++argv) |
459 | reps = atoi(*argv); | | 443 | reps = atoi(*argv); |
460 | } | | 444 | } |
461 | #endif | | 445 | #endif |
462 | | | 446 | |
463 | if (interval.tv_sec) { | | 447 | if (interval.tv_sec) { |
464 | if (!reps) | | 448 | if (!reps) |
465 | reps = -1; | | 449 | reps = -1; |
466 | } else if (reps) | | 450 | } else if (reps) |
467 | interval.tv_sec = 1; | | 451 | interval.tv_sec = 1; |
468 | | | 452 | |
469 | | | | |
470 | getnlist(todo); | | | |
471 | /* | | 453 | /* |
472 | * Statistics dumping is incompatible with the default | | 454 | * Statistics dumping is incompatible with the default |
473 | * VMSTAT/dovmstat() output. So perform the interval/reps handling | | 455 | * VMSTAT/dovmstat() output. So perform the interval/reps handling |
474 | * for it here. | | 456 | * for it here. |
475 | */ | | 457 | */ |
476 | if ((todo & (VMSTAT|VMTOTAL)) == 0) { | | 458 | if ((todo & (VMSTAT|VMTOTAL)) == 0) { |
477 | for (;;) { | | 459 | for (;;) { |
478 | if (todo & (HISTLIST|HISTDUMP)) { | | 460 | if (todo & (HISTLIST|HISTDUMP)) { |
479 | if ((todo & (HISTLIST|HISTDUMP)) == | | 461 | if ((todo & (HISTLIST|HISTDUMP)) == |
480 | (HISTLIST|HISTDUMP)) | | 462 | (HISTLIST|HISTDUMP)) |
481 | errx(1, "you may list or dump," | | 463 | errx(1, "you may list or dump," |
482 | " but not both!"); | | 464 | " but not both!"); |
483 | if (memf != NULL) | | 465 | if (memf != NULL) |
| @@ -529,56 +511,50 @@ main(int argc, char *argv[]) | | | @@ -529,56 +511,50 @@ main(int argc, char *argv[]) |
529 | errx(1, "you may not both do vmstat and vmtotal"); | | 511 | errx(1, "you may not both do vmstat and vmtotal"); |
530 | } | | 512 | } |
531 | if (todo & VMSTAT) | | 513 | if (todo & VMSTAT) |
532 | dovmstat(&interval, reps); | | 514 | dovmstat(&interval, reps); |
533 | if (todo & VMTOTAL) | | 515 | if (todo & VMTOTAL) |
534 | dovmtotal(&interval, reps); | | 516 | dovmtotal(&interval, reps); |
535 | } | | 517 | } |
536 | return 0; | | 518 | return 0; |
537 | } | | 519 | } |
538 | | | 520 | |
539 | void | | 521 | void |
540 | getnlist(int todo) | | 522 | getnlist(int todo) |
541 | { | | 523 | { |
542 | static int namelist_done = 0; | | | |
543 | static int done = 0; | | 524 | static int done = 0; |
544 | int c; | | 525 | int c; |
545 | size_t i; | | 526 | size_t i; |
546 | | | 527 | |
547 | if (kd == NULL) | | 528 | if ((c = kvm_nlist(kd, namelist)) != 0) { |
548 | errx(1, "kvm_openfiles: %s", kvm_errbuf); | | 529 | int doexit = 0; |
549 | | | 530 | if (c == -1) |
550 | if (!namelist_done) { | | 531 | errx(1, "kvm_nlist: %s %s", |
551 | namelist_done = 1; | | 532 | "namelist", kvm_geterr(kd)); |
552 | if ((c = kvm_nlist(kd, namelist)) != 0) { | | 533 | for (i = 0; i < __arraycount(namelist)-1; i++) |
553 | int doexit = 0; | | 534 | if (namelist[i].n_type == 0) { |
554 | if (c == -1) | | 535 | if (doexit++ == 0) |
555 | errx(1, "kvm_nlist: %s %s", | | 536 | (void)fprintf(stderr, |
556 | "namelist", kvm_geterr(kd)); | | 537 | "%s: undefined symbols:", |
557 | for (i = 0; i < __arraycount(namelist)-1; i++) | | 538 | getprogname()); |
558 | if (namelist[i].n_type == 0) { | | 539 | (void)fprintf(stderr, " %s", |
559 | if (doexit++ == 0) | | 540 | namelist[i].n_name); |
560 | (void)fprintf(stderr, | | | |
561 | "%s: undefined symbols:", | | | |
562 | getprogname()); | | | |
563 | (void)fprintf(stderr, " %s", | | | |
564 | namelist[i].n_name); | | | |
565 | } | | | |
566 | if (doexit) { | | | |
567 | (void)fputc('\n', stderr); | | | |
568 | exit(1); | | | |
569 | } | | 541 | } |
| | | 542 | if (doexit) { |
| | | 543 | (void)fputc('\n', stderr); |
| | | 544 | exit(1); |
570 | } | | 545 | } |
571 | } | | 546 | } |
| | | 547 | |
572 | if ((todo & (VMSTAT|INTRSTAT)) && !(done & (VMSTAT))) { | | 548 | if ((todo & (VMSTAT|INTRSTAT)) && !(done & (VMSTAT))) { |
573 | done |= VMSTAT; | | 549 | done |= VMSTAT; |
574 | if ((c = kvm_nlist(kd, timenl)) == -1 || c == X_TIMENL_SIZE) | | 550 | if ((c = kvm_nlist(kd, timenl)) == -1 || c == X_TIMENL_SIZE) |
575 | errx(1, "kvm_nlist: %s %s", "timenl", kvm_geterr(kd)); | | 551 | errx(1, "kvm_nlist: %s %s", "timenl", kvm_geterr(kd)); |
576 | } | | 552 | } |
577 | if ((todo & (SUMSTAT|INTRSTAT)) && !(done & (SUMSTAT|INTRSTAT))) { | | 553 | if ((todo & (SUMSTAT|INTRSTAT)) && !(done & (SUMSTAT|INTRSTAT))) { |
578 | done |= SUMSTAT|INTRSTAT; | | 554 | done |= SUMSTAT|INTRSTAT; |
579 | (void) kvm_nlist(kd, intrnl); | | 555 | (void) kvm_nlist(kd, intrnl); |
580 | } | | 556 | } |
581 | if ((todo & (HASHLIST|HASHSTAT)) && !(done & (HASHLIST|HASHSTAT))) { | | 557 | if ((todo & (HASHLIST|HASHSTAT)) && !(done & (HASHLIST|HASHSTAT))) { |
582 | done |= HASHLIST|HASHSTAT; | | 558 | done |= HASHLIST|HASHSTAT; |
583 | if ((c = kvm_nlist(kd, hashnl)) == -1 || c == X_HASHNL_SIZE) | | 559 | if ((c = kvm_nlist(kd, hashnl)) == -1 || c == X_HASHNL_SIZE) |
584 | errx(1, "kvm_nlist: %s %s", "hashnl", kvm_geterr(kd)); | | 560 | errx(1, "kvm_nlist: %s %s", "hashnl", kvm_geterr(kd)); |