1*2654012fSReza Sabdar /* 2*2654012fSReza Sabdar * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3*2654012fSReza Sabdar * Use is subject to license terms. 4*2654012fSReza Sabdar */ 5*2654012fSReza Sabdar 6*2654012fSReza Sabdar /* 7*2654012fSReza Sabdar * BSD 3 Clause License 8*2654012fSReza Sabdar * 9*2654012fSReza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association. 10*2654012fSReza Sabdar * 11*2654012fSReza Sabdar * Redistribution and use in source and binary forms, with or without 12*2654012fSReza Sabdar * modification, are permitted provided that the following conditions 13*2654012fSReza Sabdar * are met: 14*2654012fSReza Sabdar * - Redistributions of source code must retain the above copyright 15*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer. 16*2654012fSReza Sabdar * 17*2654012fSReza Sabdar * - Redistributions in binary form must reproduce the above copyright 18*2654012fSReza Sabdar * notice, this list of conditions and the following disclaimer in 19*2654012fSReza Sabdar * the documentation and/or other materials provided with the 20*2654012fSReza Sabdar * distribution. 21*2654012fSReza Sabdar * 22*2654012fSReza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA) 23*2654012fSReza Sabdar * nor the names of its contributors may be used to endorse or promote 24*2654012fSReza Sabdar * products derived from this software without specific prior written 25*2654012fSReza Sabdar * permission. 26*2654012fSReza Sabdar * 27*2654012fSReza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28*2654012fSReza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29*2654012fSReza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30*2654012fSReza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31*2654012fSReza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32*2654012fSReza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33*2654012fSReza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34*2654012fSReza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35*2654012fSReza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36*2654012fSReza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37*2654012fSReza Sabdar * POSSIBILITY OF SUCH DAMAGE. 38*2654012fSReza Sabdar */ 39*2654012fSReza Sabdar #include <stdio.h> 40*2654012fSReza Sabdar #include <stdlib.h> 41*2654012fSReza Sabdar #include <stdarg.h> 42*2654012fSReza Sabdar #include <ctype.h> 43*2654012fSReza Sabdar #include <unistd.h> 44*2654012fSReza Sabdar #include <memory.h> 45*2654012fSReza Sabdar #include <string.h> 46*2654012fSReza Sabdar #include <fcntl.h> 47*2654012fSReza Sabdar #include <errno.h> 48*2654012fSReza Sabdar #include <signal.h> 49*2654012fSReza Sabdar #include <values.h> 50*2654012fSReza Sabdar #include <poll.h> 51*2654012fSReza Sabdar #include <locale.h> 52*2654012fSReza Sabdar #include <libndmp.h> 53*2654012fSReza Sabdar 54*2654012fSReza Sabdar #define MAX_DEV_STAT 16 55*2654012fSReza Sabdar #define REPRINT 19 56*2654012fSReza Sabdar #define VAL(v) (new->ns_##v) 57*2654012fSReza Sabdar #define DELTA(v) (new->ns_##v - (old ? old->ns_##v : 0)) 58*2654012fSReza Sabdar #define ADJ(n) ((adj <= 0) ? n : (adj >= n) ? 1 : n - adj) 59*2654012fSReza Sabdar #define adjprintf(fmt, n, val) adj -= (n + 1) - printf(fmt, ADJ(n), val) 60*2654012fSReza Sabdar #if !defined(TEXT_DOMAIN) 61*2654012fSReza Sabdar #define TEXT_DOMAIN "SYS_TEST" 62*2654012fSReza Sabdar #endif 63*2654012fSReza Sabdar 64*2654012fSReza Sabdar static int adj; /* number of excess columns */ 65*2654012fSReza Sabdar static long iter = 0; 66*2654012fSReza Sabdar static int blksize = 1024; 67*2654012fSReza Sabdar static int poll_interval = 1; 68*2654012fSReza Sabdar static ndmp_stat_t *nstat; 69*2654012fSReza Sabdar static int lines = 1; 70*2654012fSReza Sabdar 71*2654012fSReza Sabdar static void dostats(ndmp_stat_t *, ndmp_stat_t *); 72*2654012fSReza Sabdar static void printhdr(int); 73*2654012fSReza Sabdar static void usage(void); 74*2654012fSReza Sabdar 75*2654012fSReza Sabdar int 76*2654012fSReza Sabdar main(int argc, char **argv) 77*2654012fSReza Sabdar { 78*2654012fSReza Sabdar ndmp_stat_t *old = NULL; 79*2654012fSReza Sabdar 80*2654012fSReza Sabdar (void) setlocale(LC_ALL, ""); 81*2654012fSReza Sabdar (void) textdomain(TEXT_DOMAIN); 82*2654012fSReza Sabdar 83*2654012fSReza Sabdar argc--, argv++; 84*2654012fSReza Sabdar 85*2654012fSReza Sabdar if (argc > 0) { 86*2654012fSReza Sabdar long interval; 87*2654012fSReza Sabdar char *endptr; 88*2654012fSReza Sabdar 89*2654012fSReza Sabdar errno = 0; 90*2654012fSReza Sabdar interval = strtol(argv[0], &endptr, 10); 91*2654012fSReza Sabdar 92*2654012fSReza Sabdar if (errno > 0 || *endptr != '\0' || interval <= 0 || 93*2654012fSReza Sabdar interval > MAXLONG) { 94*2654012fSReza Sabdar usage(); 95*2654012fSReza Sabdar return (1); 96*2654012fSReza Sabdar } 97*2654012fSReza Sabdar poll_interval = 1000 * interval; 98*2654012fSReza Sabdar if (poll_interval <= 0) { 99*2654012fSReza Sabdar usage(); 100*2654012fSReza Sabdar return (1); 101*2654012fSReza Sabdar } 102*2654012fSReza Sabdar iter = MAXLONG; 103*2654012fSReza Sabdar if (argc > 1) { 104*2654012fSReza Sabdar iter = strtol(argv[1], NULL, 10); 105*2654012fSReza Sabdar if (errno > 0 || *endptr != '\0' || iter <= 0) { 106*2654012fSReza Sabdar usage(); 107*2654012fSReza Sabdar return (1); 108*2654012fSReza Sabdar } 109*2654012fSReza Sabdar } 110*2654012fSReza Sabdar if (argc > 2) { 111*2654012fSReza Sabdar usage(); 112*2654012fSReza Sabdar return (1); 113*2654012fSReza Sabdar } 114*2654012fSReza Sabdar } 115*2654012fSReza Sabdar 116*2654012fSReza Sabdar if (ndmp_door_status()) { 117*2654012fSReza Sabdar (void) fprintf(stdout, 118*2654012fSReza Sabdar gettext(" Error: ndmpd service not running.\n")); 119*2654012fSReza Sabdar return (1); 120*2654012fSReza Sabdar } 121*2654012fSReza Sabdar 122*2654012fSReza Sabdar (void) sigset(SIGCONT, printhdr); 123*2654012fSReza Sabdar 124*2654012fSReza Sabdar printhdr(0); 125*2654012fSReza Sabdar 126*2654012fSReza Sabdar if ((nstat = malloc(sizeof (ndmp_stat_t))) == NULL) { 127*2654012fSReza Sabdar (void) fprintf(stdout, gettext("Out of memory")); 128*2654012fSReza Sabdar return (1); 129*2654012fSReza Sabdar } 130*2654012fSReza Sabdar 131*2654012fSReza Sabdar 132*2654012fSReza Sabdar if (ndmp_get_stats(nstat) != 0) { 133*2654012fSReza Sabdar free(nstat); 134*2654012fSReza Sabdar return (1); 135*2654012fSReza Sabdar } 136*2654012fSReza Sabdar 137*2654012fSReza Sabdar dostats(old, nstat); 138*2654012fSReza Sabdar while (--iter > 0) { 139*2654012fSReza Sabdar (void) poll(NULL, 0, poll_interval); 140*2654012fSReza Sabdar 141*2654012fSReza Sabdar free(old); 142*2654012fSReza Sabdar old = nstat; 143*2654012fSReza Sabdar if ((nstat = malloc(sizeof (ndmp_stat_t))) == NULL) { 144*2654012fSReza Sabdar (void) fprintf(stdout, gettext("Out of memory")); 145*2654012fSReza Sabdar free(old); 146*2654012fSReza Sabdar return (1); 147*2654012fSReza Sabdar } 148*2654012fSReza Sabdar if (ndmp_get_stats(nstat) != 0) { 149*2654012fSReza Sabdar free(old); 150*2654012fSReza Sabdar free(nstat); 151*2654012fSReza Sabdar return (1); 152*2654012fSReza Sabdar } 153*2654012fSReza Sabdar dostats(old, nstat); 154*2654012fSReza Sabdar } 155*2654012fSReza Sabdar 156*2654012fSReza Sabdar return (0); 157*2654012fSReza Sabdar } 158*2654012fSReza Sabdar 159*2654012fSReza Sabdar /* ARGSUSED */ 160*2654012fSReza Sabdar static void 161*2654012fSReza Sabdar printhdr(int sig) 162*2654012fSReza Sabdar { 163*2654012fSReza Sabdar (void) printf(" wthr ops file disk tape "); 164*2654012fSReza Sabdar (void) printf("bytes perf prcnt\n"); 165*2654012fSReza Sabdar 166*2654012fSReza Sabdar (void) printf(" r w bk rs rd wr rd wr rd wr rd "); 167*2654012fSReza Sabdar (void) printf("wr bk rs dsk tpe idl\n"); 168*2654012fSReza Sabdar 169*2654012fSReza Sabdar lines = REPRINT; 170*2654012fSReza Sabdar } 171*2654012fSReza Sabdar 172*2654012fSReza Sabdar static void 173*2654012fSReza Sabdar dostats(ndmp_stat_t *old, ndmp_stat_t *new) 174*2654012fSReza Sabdar { 175*2654012fSReza Sabdar long long dskop = 0; 176*2654012fSReza Sabdar long long tpop = 0; 177*2654012fSReza Sabdar long dpcnt, tpcnt; 178*2654012fSReza Sabdar long ipcnt; 179*2654012fSReza Sabdar int totl; 180*2654012fSReza Sabdar long rbytes; 181*2654012fSReza Sabdar long wbytes; 182*2654012fSReza Sabdar 183*2654012fSReza Sabdar adj = 0; 184*2654012fSReza Sabdar 185*2654012fSReza Sabdar if (--lines == 0) 186*2654012fSReza Sabdar printhdr(0); 187*2654012fSReza Sabdar 188*2654012fSReza Sabdar if (!old) { 189*2654012fSReza Sabdar (void) printf(" 0 0 0 0 0 0 0 "); 190*2654012fSReza Sabdar (void) printf("0 0 0 0 0 0 0 0 0 100\n"); 191*2654012fSReza Sabdar return; 192*2654012fSReza Sabdar } 193*2654012fSReza Sabdar 194*2654012fSReza Sabdar adjprintf(" %*u", 1, VAL(trun)); 195*2654012fSReza Sabdar adjprintf(" %*u", 1, VAL(twait)); 196*2654012fSReza Sabdar adjprintf(" %*u", 2, VAL(nbk)); 197*2654012fSReza Sabdar adjprintf(" %*u", 2, VAL(nrs)); 198*2654012fSReza Sabdar adjprintf(" %*u", 4, DELTA(rfile)); 199*2654012fSReza Sabdar adjprintf(" %*u", 4, DELTA(wfile)); 200*2654012fSReza Sabdar adjprintf(" %*u", 4, (unsigned)(DELTA(rdisk) / blksize)); 201*2654012fSReza Sabdar adjprintf(" %*u", 4, (unsigned)(DELTA(wdisk) / blksize)); 202*2654012fSReza Sabdar adjprintf(" %*u", 4, (unsigned)(DELTA(rtape) / blksize)); 203*2654012fSReza Sabdar adjprintf(" %*u", 4, (unsigned)(DELTA(wtape) / blksize)); 204*2654012fSReza Sabdar 205*2654012fSReza Sabdar /* Get the average throughput */ 206*2654012fSReza Sabdar rbytes = (DELTA(wtape) + DELTA(rdisk)) / 2; 207*2654012fSReza Sabdar wbytes = (DELTA(rtape) + DELTA(wdisk)) / 2; 208*2654012fSReza Sabdar rbytes /= blksize; 209*2654012fSReza Sabdar wbytes /= blksize; 210*2654012fSReza Sabdar 211*2654012fSReza Sabdar adjprintf(" %*lu", 4, rbytes); 212*2654012fSReza Sabdar adjprintf(" %*lu", 4, wbytes); 213*2654012fSReza Sabdar 214*2654012fSReza Sabdar adjprintf(" %*lu", 3, rbytes / poll_interval); 215*2654012fSReza Sabdar adjprintf(" %*lu", 2, wbytes / poll_interval); 216*2654012fSReza Sabdar 217*2654012fSReza Sabdar dskop += DELTA(rdisk); 218*2654012fSReza Sabdar dskop += DELTA(wdisk); 219*2654012fSReza Sabdar tpop += DELTA(rtape); 220*2654012fSReza Sabdar tpop += DELTA(wtape); 221*2654012fSReza Sabdar totl = (dskop + tpop) ? (dskop + tpop) : 1; 222*2654012fSReza Sabdar 223*2654012fSReza Sabdar dpcnt = (dskop * 100) / totl; 224*2654012fSReza Sabdar tpcnt = (tpop * 100) / totl; 225*2654012fSReza Sabdar ipcnt = 100 - dpcnt - tpcnt; 226*2654012fSReza Sabdar 227*2654012fSReza Sabdar adjprintf(" %*lu", 4, dpcnt); 228*2654012fSReza Sabdar adjprintf(" %*lu", 3, tpcnt); 229*2654012fSReza Sabdar adjprintf(" %*lu\n", 3, ipcnt); 230*2654012fSReza Sabdar (void) fflush(stdout); 231*2654012fSReza Sabdar } 232*2654012fSReza Sabdar 233*2654012fSReza Sabdar static void 234*2654012fSReza Sabdar usage(void) 235*2654012fSReza Sabdar { 236*2654012fSReza Sabdar (void) fprintf(stderr, "Usage: ndmpstat [interval [count]]\n"); 237*2654012fSReza Sabdar } 238