/* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * BSD 3 Clause License * * Copyright (c) 2007, The Storage Networking Industry Association. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither the name of The Storage Networking Industry Association (SNIA) * nor the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_DEV_STAT 16 #define REPRINT 19 #define VAL(v) (new->ns_##v) #define DELTA(v) (new->ns_##v - (old ? old->ns_##v : 0)) #define ADJ(n) ((adj <= 0) ? n : (adj >= n) ? 1 : n - adj) #define adjprintf(fmt, n, val) adj -= (n + 1) - printf(fmt, ADJ(n), val) #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif static int adj; /* number of excess columns */ static long iter = 0; static int blksize = 1024; static int poll_interval = 1; static ndmp_stat_t *nstat; static int lines = 1; static void dostats(ndmp_stat_t *, ndmp_stat_t *); static void printhdr(int); static void usage(void); int main(int argc, char **argv) { ndmp_stat_t *old = NULL; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); argc--, argv++; if (argc > 0) { long interval; char *endptr; errno = 0; interval = strtol(argv[0], &endptr, 10); if (errno > 0 || *endptr != '\0' || interval <= 0 || interval > MAXLONG) { usage(); return (1); } poll_interval = 1000 * interval; if (poll_interval <= 0) { usage(); return (1); } iter = MAXLONG; if (argc > 1) { iter = strtol(argv[1], NULL, 10); if (errno > 0 || *endptr != '\0' || iter <= 0) { usage(); return (1); } } if (argc > 2) { usage(); return (1); } } if (ndmp_door_status()) { (void) fprintf(stdout, gettext(" Error: ndmpd service not running.\n")); return (1); } (void) sigset(SIGCONT, printhdr); printhdr(0); if ((nstat = malloc(sizeof (ndmp_stat_t))) == NULL) { (void) fprintf(stdout, gettext("Out of memory")); return (1); } if (ndmp_get_stats(nstat) != 0) { free(nstat); return (1); } dostats(old, nstat); while (--iter > 0) { (void) poll(NULL, 0, poll_interval); free(old); old = nstat; if ((nstat = malloc(sizeof (ndmp_stat_t))) == NULL) { (void) fprintf(stdout, gettext("Out of memory")); free(old); return (1); } if (ndmp_get_stats(nstat) != 0) { free(old); free(nstat); return (1); } dostats(old, nstat); } return (0); } /* ARGSUSED */ static void printhdr(int sig) { (void) printf(" wthr ops file disk tape "); (void) printf("bytes perf prcnt\n"); (void) printf(" r w bk rs rd wr rd wr rd wr rd "); (void) printf("wr bk rs dsk tpe idl\n"); lines = REPRINT; } static void dostats(ndmp_stat_t *old, ndmp_stat_t *new) { long long dskop = 0; long long tpop = 0; long dpcnt, tpcnt; long ipcnt; int totl; long rbytes; long wbytes; adj = 0; if (--lines == 0) printhdr(0); if (!old) { (void) printf(" 0 0 0 0 0 0 0 "); (void) printf("0 0 0 0 0 0 0 0 0 100\n"); return; } adjprintf(" %*u", 1, VAL(trun)); adjprintf(" %*u", 1, VAL(twait)); adjprintf(" %*u", 2, VAL(nbk)); adjprintf(" %*u", 2, VAL(nrs)); adjprintf(" %*u", 4, DELTA(rfile)); adjprintf(" %*u", 4, DELTA(wfile)); adjprintf(" %*u", 4, (unsigned)(DELTA(rdisk) / blksize)); adjprintf(" %*u", 4, (unsigned)(DELTA(wdisk) / blksize)); adjprintf(" %*u", 4, (unsigned)(DELTA(rtape) / blksize)); adjprintf(" %*u", 4, (unsigned)(DELTA(wtape) / blksize)); /* Get the average throughput */ rbytes = (DELTA(wtape) + DELTA(rdisk)) / 2; wbytes = (DELTA(rtape) + DELTA(wdisk)) / 2; rbytes /= blksize; wbytes /= blksize; adjprintf(" %*lu", 4, rbytes); adjprintf(" %*lu", 4, wbytes); adjprintf(" %*lu", 3, rbytes / poll_interval); adjprintf(" %*lu", 2, wbytes / poll_interval); dskop += DELTA(rdisk); dskop += DELTA(wdisk); tpop += DELTA(rtape); tpop += DELTA(wtape); totl = (dskop + tpop) ? (dskop + tpop) : 1; dpcnt = (dskop * 100) / totl; tpcnt = (tpop * 100) / totl; ipcnt = 100 - dpcnt - tpcnt; adjprintf(" %*lu", 4, dpcnt); adjprintf(" %*lu", 3, tpcnt); adjprintf(" %*lu\n", 3, ipcnt); (void) fflush(stdout); } static void usage(void) { (void) fprintf(stderr, "Usage: ndmpstat [interval [count]]\n"); }