xref: /onnv-gate/usr/src/cmd/avs/dsstat/dsstat.c (revision 11576:b23c42c0c9d6)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
22*11576SSurya.Prakki@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include <stdio.h>
277836SJohn.Forte@Sun.COM #include <stdlib.h>
287836SJohn.Forte@Sun.COM #include <string.h>
297836SJohn.Forte@Sun.COM #include <unistd.h>
307836SJohn.Forte@Sun.COM #include <errno.h>
317836SJohn.Forte@Sun.COM #include <inttypes.h>
327836SJohn.Forte@Sun.COM #include <locale.h>
337836SJohn.Forte@Sun.COM 
347836SJohn.Forte@Sun.COM #include <kstat.h>
357836SJohn.Forte@Sun.COM 
367836SJohn.Forte@Sun.COM #include "dsstat.h"
377836SJohn.Forte@Sun.COM #include "multi_stats.h"
387836SJohn.Forte@Sun.COM 
397836SJohn.Forte@Sun.COM /* Globals */
407836SJohn.Forte@Sun.COM int mode = 0;
417836SJohn.Forte@Sun.COM int interval = 1;
427836SJohn.Forte@Sun.COM int iterations = 1;
437836SJohn.Forte@Sun.COM int zflag = 0;
447836SJohn.Forte@Sun.COM int linesout = 0;
457836SJohn.Forte@Sun.COM 
467836SJohn.Forte@Sun.COM short hflags = HEADERS_EXL;
477836SJohn.Forte@Sun.COM short dflags = 0;
487836SJohn.Forte@Sun.COM short rflags = 0;
497836SJohn.Forte@Sun.COM vslist_t *vs_top = NULL;
507836SJohn.Forte@Sun.COM 
517836SJohn.Forte@Sun.COM void
errout(char * msg)527836SJohn.Forte@Sun.COM errout(char *msg)
537836SJohn.Forte@Sun.COM {
547836SJohn.Forte@Sun.COM 
557836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, msg);
567836SJohn.Forte@Sun.COM }
577836SJohn.Forte@Sun.COM 
587836SJohn.Forte@Sun.COM void
usage()597836SJohn.Forte@Sun.COM usage()
607836SJohn.Forte@Sun.COM {
617836SJohn.Forte@Sun.COM 	errout(gettext(
627836SJohn.Forte@Sun.COM 	    "\ndsstat [-m <mode>[,<mode>]] [-f | -F] [-z] [-s <sets>] "
637836SJohn.Forte@Sun.COM 	    "[-r <flags>] \\\n[-d <flags>] [<interval> [<count>]]\n\n"));
647836SJohn.Forte@Sun.COM }
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM void
help()677836SJohn.Forte@Sun.COM help()
687836SJohn.Forte@Sun.COM {
697836SJohn.Forte@Sun.COM 	usage();
707836SJohn.Forte@Sun.COM 
717836SJohn.Forte@Sun.COM 	errout(gettext("\t"
727836SJohn.Forte@Sun.COM 	    "-d <flags> Specifies the statistics to be displayed\n\n"));
737836SJohn.Forte@Sun.COM 	errout(gettext("\t"
747836SJohn.Forte@Sun.COM 	    "   For 'cache' mode\n"));
757836SJohn.Forte@Sun.COM 	errout(gettext("\t"
767836SJohn.Forte@Sun.COM 	    "      Valid <flags> are 'rwfsdc', default <flags> are 'sf'\n"));
777836SJohn.Forte@Sun.COM 	errout(gettext("\t"
787836SJohn.Forte@Sun.COM 	    "      r=read, w=write, f=flags, s=summary,\n"));
797836SJohn.Forte@Sun.COM 	errout(gettext("\t"
807836SJohn.Forte@Sun.COM 	    "   only available for cache mode, need to combine with '-m'\n"));
817836SJohn.Forte@Sun.COM 	errout(gettext("\t"
827836SJohn.Forte@Sun.COM 	    "      d=destaged, c=write cancellations\n\n"));
837836SJohn.Forte@Sun.COM 	errout(gettext("\t"
847836SJohn.Forte@Sun.COM 	    "   For 'ii' mode;\n"));
857836SJohn.Forte@Sun.COM 	errout(gettext("\t"
867836SJohn.Forte@Sun.COM 	    "      Valid <flags> are 'rwtfps', default <flags> are 'sf'\n"));
877836SJohn.Forte@Sun.COM 	errout(gettext("\t"
887836SJohn.Forte@Sun.COM 	    "      r=read, w=write, t=timing, f=flags, p=percentages,\n"));
897836SJohn.Forte@Sun.COM 	errout(gettext("\t"
907836SJohn.Forte@Sun.COM 	    "      s=summary\n\n"));
917836SJohn.Forte@Sun.COM 	errout(gettext("\t"
927836SJohn.Forte@Sun.COM 	    "   For 'sndr' mode;\n"));
937836SJohn.Forte@Sun.COM 	errout(gettext("\t"
947836SJohn.Forte@Sun.COM 	    "      Valid <flags> are'rwtfpsq', default <flags> are 'spf'\n"));
957836SJohn.Forte@Sun.COM 	errout(gettext("\t"
967836SJohn.Forte@Sun.COM 	    "      r=read, w=write, t=timing, f=flags, p=percentages,\n"));
977836SJohn.Forte@Sun.COM 	errout(gettext("\t"
987836SJohn.Forte@Sun.COM 	    "      s=summary\n"));
997836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1007836SJohn.Forte@Sun.COM 	    "   only available for sndr mode, need to combine with '-m'\n"));
1017836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1027836SJohn.Forte@Sun.COM 	    "      q=queue\n\n"));
1037836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1047836SJohn.Forte@Sun.COM 	    "-f  prints field headers once for each iteration\n\n"));
1057836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1067836SJohn.Forte@Sun.COM 	    "-F  prints field headers once, at the start of reporting\n\n"));
1077836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1087836SJohn.Forte@Sun.COM 	    "-h  prints detailed usage message\n\n"));
1097836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1107836SJohn.Forte@Sun.COM 	    "-m <mode>[,<mode>] where mode is, 'cache', 'ii', or 'sndr'\n\n"));
1117836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1127836SJohn.Forte@Sun.COM 	    "   Multiple modes may be specified as a comma separated list,\n"));
1137836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1147836SJohn.Forte@Sun.COM 	    "   or multiple -m switches may be used.\n\n"));
1157836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1167836SJohn.Forte@Sun.COM 	    "-r <flags> specifies components to be reported\n\n"));
1177836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1187836SJohn.Forte@Sun.COM 	    "   For 'cache' mode, this option is not used.\n\n"));
1197836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1207836SJohn.Forte@Sun.COM 	    "   For 'ii' mode;\n"));
1217836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1227836SJohn.Forte@Sun.COM 	    "      Valid <flags> are 'msbo', default <flags> are 'msbo'\n"));
1237836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1247836SJohn.Forte@Sun.COM 	    "      m=master, s=shadow, b=bitmap, o=overflow\n\n"));
1257836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1267836SJohn.Forte@Sun.COM 	    "   For 'sndr' mode;\n"));
1277836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1287836SJohn.Forte@Sun.COM 	    "      Valid <flags> are 'nb', default <flags> are 'nb'\n"));
1297836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1307836SJohn.Forte@Sun.COM 	    "      n=network, b=bitmap\n\n"));
1317836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1327836SJohn.Forte@Sun.COM 	    "-s <sets> outputs specified sets\n"));
1337836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1347836SJohn.Forte@Sun.COM 	    "    Where <sets> is a comma delimited list of set names\n\n"));
1357836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1367836SJohn.Forte@Sun.COM 	    "-z  suppress reports with zero value (no activity)\n\n"));
1377836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1387836SJohn.Forte@Sun.COM 	    "<interval> is the number of seconds between reports\n\n"));
1397836SJohn.Forte@Sun.COM 	errout(gettext("\t"
1407836SJohn.Forte@Sun.COM 	    "<count> is the number of reports to be generated\n\n"));
1417836SJohn.Forte@Sun.COM }
1427836SJohn.Forte@Sun.COM 
1437836SJohn.Forte@Sun.COM void
fail(int err,char * msg)1447836SJohn.Forte@Sun.COM fail(int err, char *msg)
1457836SJohn.Forte@Sun.COM {
1467836SJohn.Forte@Sun.COM 	errout(gettext("\ndsstat: "));
1477836SJohn.Forte@Sun.COM 	errout(msg);
1487836SJohn.Forte@Sun.COM 
1497836SJohn.Forte@Sun.COM 	usage();
1507836SJohn.Forte@Sun.COM 
1517836SJohn.Forte@Sun.COM 	errout(gettext("For detailed usage run \"dsstat -h\"\n"));
1527836SJohn.Forte@Sun.COM 
1537836SJohn.Forte@Sun.COM 	exit(err);
1547836SJohn.Forte@Sun.COM }
1557836SJohn.Forte@Sun.COM 
1567836SJohn.Forte@Sun.COM int
set_mode(char * user_modes)1577836SJohn.Forte@Sun.COM set_mode(char *user_modes)
1587836SJohn.Forte@Sun.COM {
1597836SJohn.Forte@Sun.COM 	char *m;
1607836SJohn.Forte@Sun.COM 	int local_mode = 0;
1617836SJohn.Forte@Sun.COM 
1627836SJohn.Forte@Sun.COM 	for (m = strtok(user_modes, ","); m != NULL; m = strtok(NULL, ",")) {
1637836SJohn.Forte@Sun.COM 		if (local_mode != 0) {
1647836SJohn.Forte@Sun.COM 			local_mode |= MULTI;
1657836SJohn.Forte@Sun.COM 		}
1667836SJohn.Forte@Sun.COM 
1677836SJohn.Forte@Sun.COM 		if (strncasecmp("sndr", m, strlen(m)) == 0) {
1687836SJohn.Forte@Sun.COM 			local_mode |= SNDR;
1697836SJohn.Forte@Sun.COM 			continue;
1707836SJohn.Forte@Sun.COM 		}
1717836SJohn.Forte@Sun.COM 
1727836SJohn.Forte@Sun.COM 		if (strncasecmp("ii", m, strlen(m)) == 0) {
1737836SJohn.Forte@Sun.COM 			local_mode |= IIMG;
1747836SJohn.Forte@Sun.COM 			continue;
1757836SJohn.Forte@Sun.COM 		}
1767836SJohn.Forte@Sun.COM 
1777836SJohn.Forte@Sun.COM 		if (strncasecmp("cache", m, strlen(m)) == 0) {
1787836SJohn.Forte@Sun.COM 			local_mode |= SDBC;
1797836SJohn.Forte@Sun.COM 			continue;
1807836SJohn.Forte@Sun.COM 		}
1817836SJohn.Forte@Sun.COM 
1827836SJohn.Forte@Sun.COM 		fail(DSSTAT_EINVAL, gettext("Invalid mode specified"));
1837836SJohn.Forte@Sun.COM 	}
1847836SJohn.Forte@Sun.COM 
1857836SJohn.Forte@Sun.COM 	return (local_mode);
1867836SJohn.Forte@Sun.COM }
1877836SJohn.Forte@Sun.COM 
1887836SJohn.Forte@Sun.COM short
set_dflags(char * flags)1897836SJohn.Forte@Sun.COM set_dflags(char *flags)
1907836SJohn.Forte@Sun.COM {
1917836SJohn.Forte@Sun.COM 	int index;
1927836SJohn.Forte@Sun.COM 	short user_dflags = 0;
1937836SJohn.Forte@Sun.COM 
1947836SJohn.Forte@Sun.COM 	for (index = 0; index < strlen(flags); index++) {
1957836SJohn.Forte@Sun.COM 		switch (flags[index]) {
1967836SJohn.Forte@Sun.COM 			case 'r':
1977836SJohn.Forte@Sun.COM 				user_dflags |= READ;
1987836SJohn.Forte@Sun.COM 				break;
1997836SJohn.Forte@Sun.COM 			case 'w':
2007836SJohn.Forte@Sun.COM 				user_dflags |= WRITE;
2017836SJohn.Forte@Sun.COM 				break;
2027836SJohn.Forte@Sun.COM 			case 't':
2037836SJohn.Forte@Sun.COM 				user_dflags |= TIMING;
2047836SJohn.Forte@Sun.COM 				break;
2057836SJohn.Forte@Sun.COM 			case 'f':
2067836SJohn.Forte@Sun.COM 				user_dflags |= FLAGS;
2077836SJohn.Forte@Sun.COM 				break;
2087836SJohn.Forte@Sun.COM 			case 'p':
2097836SJohn.Forte@Sun.COM 				user_dflags |= PCTS;
2107836SJohn.Forte@Sun.COM 				break;
2117836SJohn.Forte@Sun.COM 			case 's':
2127836SJohn.Forte@Sun.COM 				user_dflags |= SUMMARY;
2137836SJohn.Forte@Sun.COM 				break;
2147836SJohn.Forte@Sun.COM 			case 'd':
2157836SJohn.Forte@Sun.COM 				user_dflags |= DESTAGED;
2167836SJohn.Forte@Sun.COM 				break;
2177836SJohn.Forte@Sun.COM 			case 'c':
2187836SJohn.Forte@Sun.COM 				user_dflags |= WRCANCEL;
2197836SJohn.Forte@Sun.COM 				break;
2207836SJohn.Forte@Sun.COM 			case 'h':
2217836SJohn.Forte@Sun.COM 				user_dflags |= RATIO;
2227836SJohn.Forte@Sun.COM 				break;
2237836SJohn.Forte@Sun.COM 			case 'q':
2247836SJohn.Forte@Sun.COM 				user_dflags |= ASYNC_QUEUE;
2257836SJohn.Forte@Sun.COM 				break;
2267836SJohn.Forte@Sun.COM 			default:
2277836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
2287836SJohn.Forte@Sun.COM 				    gettext("Invalid display-flags set\n"));
2297836SJohn.Forte@Sun.COM 		}
2307836SJohn.Forte@Sun.COM 	}
2317836SJohn.Forte@Sun.COM 
2327836SJohn.Forte@Sun.COM 	return (user_dflags);
2337836SJohn.Forte@Sun.COM }
2347836SJohn.Forte@Sun.COM 
2357836SJohn.Forte@Sun.COM short
set_rflags(char * flags)2367836SJohn.Forte@Sun.COM set_rflags(char *flags)
2377836SJohn.Forte@Sun.COM {
2387836SJohn.Forte@Sun.COM 	int index;
2397836SJohn.Forte@Sun.COM 	short user_rflags = 0;
2407836SJohn.Forte@Sun.COM 
2417836SJohn.Forte@Sun.COM 	for (index = 0; index < strlen(flags); index++) {
2427836SJohn.Forte@Sun.COM 		switch (flags[index]) {
2437836SJohn.Forte@Sun.COM 			case 'm':
2447836SJohn.Forte@Sun.COM 				user_rflags |= IIMG_MST;
2457836SJohn.Forte@Sun.COM 				break;
2467836SJohn.Forte@Sun.COM 			case 's':
2477836SJohn.Forte@Sun.COM 				user_rflags |= IIMG_SHD;
2487836SJohn.Forte@Sun.COM 				break;
2497836SJohn.Forte@Sun.COM 			case 'b':
2507836SJohn.Forte@Sun.COM 				user_rflags |= IIMG_BMP;
2517836SJohn.Forte@Sun.COM 				user_rflags |= SNDR_BMP;
2527836SJohn.Forte@Sun.COM 				break;
2537836SJohn.Forte@Sun.COM 			case 'o':
2547836SJohn.Forte@Sun.COM 				user_rflags |= IIMG_OVR;
2557836SJohn.Forte@Sun.COM 				break;
2567836SJohn.Forte@Sun.COM 			case 'n':
2577836SJohn.Forte@Sun.COM 				user_rflags |= SNDR_NET;
2587836SJohn.Forte@Sun.COM 				break;
2597836SJohn.Forte@Sun.COM 			default:
2607836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
2617836SJohn.Forte@Sun.COM 				    gettext("Invalid report-flags set\n"));
2627836SJohn.Forte@Sun.COM 		}
2637836SJohn.Forte@Sun.COM 	}
2647836SJohn.Forte@Sun.COM 
2657836SJohn.Forte@Sun.COM 	return (user_rflags);
2667836SJohn.Forte@Sun.COM }
2677836SJohn.Forte@Sun.COM 
2687836SJohn.Forte@Sun.COM void
set_vol_list(char * list)2697836SJohn.Forte@Sun.COM set_vol_list(char *list)
2707836SJohn.Forte@Sun.COM {
2717836SJohn.Forte@Sun.COM 	vslist_t *pre;
2727836SJohn.Forte@Sun.COM 	vslist_t *newvol;
2737836SJohn.Forte@Sun.COM 	vslist_t *vslist;
2747836SJohn.Forte@Sun.COM 	char *volume;
2757836SJohn.Forte@Sun.COM 
2767836SJohn.Forte@Sun.COM 	for (volume = strtok(list, ","); volume != NULL;
2777836SJohn.Forte@Sun.COM 	    volume = strtok(NULL, ",")) {
2787836SJohn.Forte@Sun.COM 		int dup = 0;
2797836SJohn.Forte@Sun.COM 		char *vh = NULL;
2807836SJohn.Forte@Sun.COM 		char *vn = NULL;
2817836SJohn.Forte@Sun.COM 
2827836SJohn.Forte@Sun.COM 		/* get user-specified set information */
2837836SJohn.Forte@Sun.COM 		if ((vn = strchr(volume, ':')) == NULL) {
2847836SJohn.Forte@Sun.COM 			vn = volume;
2857836SJohn.Forte@Sun.COM 		} else {
2867836SJohn.Forte@Sun.COM 			*vn = '\0';
2877836SJohn.Forte@Sun.COM 			vn++;
2887836SJohn.Forte@Sun.COM 			vh = volume;
2897836SJohn.Forte@Sun.COM 		}
2907836SJohn.Forte@Sun.COM 
2917836SJohn.Forte@Sun.COM 		/* check for duplicates */
2927836SJohn.Forte@Sun.COM 		dup = 0;
2937836SJohn.Forte@Sun.COM 
2947836SJohn.Forte@Sun.COM 		for (vslist = vs_top; vslist != NULL; vslist = vslist->next) {
2957836SJohn.Forte@Sun.COM 			if (vslist->volhost && vh) {
2967836SJohn.Forte@Sun.COM 				if (strcmp(vslist->volhost, vh) == 0 &&
2977836SJohn.Forte@Sun.COM 				    strcmp(vslist->volname, vn) == 0)
2987836SJohn.Forte@Sun.COM 					dup = 1;
2997836SJohn.Forte@Sun.COM 			} else {
3007836SJohn.Forte@Sun.COM 				if (strcmp(vslist->volname, vn) == 0)
3017836SJohn.Forte@Sun.COM 					dup = 1;
3027836SJohn.Forte@Sun.COM 			}
3037836SJohn.Forte@Sun.COM 
3047836SJohn.Forte@Sun.COM 			pre = vslist;
3057836SJohn.Forte@Sun.COM 		}
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM 		if (dup)
3087836SJohn.Forte@Sun.COM 			continue;
3097836SJohn.Forte@Sun.COM 
3107836SJohn.Forte@Sun.COM 		/* initialize new vslist record */
3117836SJohn.Forte@Sun.COM 		newvol = (vslist_t *)calloc(1, sizeof (vslist_t));
3127836SJohn.Forte@Sun.COM 
3137836SJohn.Forte@Sun.COM 		newvol->volname = (char *)calloc((strlen(vn) + 1),
314*11576SSurya.Prakki@Sun.COM 		    sizeof (char));
315*11576SSurya.Prakki@Sun.COM 		(void) strcpy(newvol->volname, vn);
3167836SJohn.Forte@Sun.COM 
3177836SJohn.Forte@Sun.COM 		if (vh == NULL)
3187836SJohn.Forte@Sun.COM 			goto save;
3197836SJohn.Forte@Sun.COM 
3207836SJohn.Forte@Sun.COM 		newvol->volhost = (char *)calloc((strlen(vh) + 1),
321*11576SSurya.Prakki@Sun.COM 		    sizeof (char));
322*11576SSurya.Prakki@Sun.COM 		(void) strcpy(newvol->volhost, vh);
3237836SJohn.Forte@Sun.COM 
3247836SJohn.Forte@Sun.COM save:
3257836SJohn.Forte@Sun.COM 		/* save record */
3267836SJohn.Forte@Sun.COM 		if (vs_top == NULL) {
3277836SJohn.Forte@Sun.COM 			vslist = vs_top = newvol;
3287836SJohn.Forte@Sun.COM 			vslist->next = NULL;
3297836SJohn.Forte@Sun.COM 			continue;
3307836SJohn.Forte@Sun.COM 		}
3317836SJohn.Forte@Sun.COM 
3327836SJohn.Forte@Sun.COM 		if (vslist == NULL) {
3337836SJohn.Forte@Sun.COM 			vslist = pre->next = newvol;
3347836SJohn.Forte@Sun.COM 			vslist->next = NULL;
3357836SJohn.Forte@Sun.COM 			continue;
3367836SJohn.Forte@Sun.COM 		}
3377836SJohn.Forte@Sun.COM 	}
3387836SJohn.Forte@Sun.COM }
3397836SJohn.Forte@Sun.COM 
3407836SJohn.Forte@Sun.COM int
main(int argc,char ** argv)3417836SJohn.Forte@Sun.COM main(int argc, char **argv)
3427836SJohn.Forte@Sun.COM {
3437836SJohn.Forte@Sun.COM 	extern char *optarg;
3447836SJohn.Forte@Sun.COM 	extern int optind;
3457836SJohn.Forte@Sun.COM 
3467836SJohn.Forte@Sun.COM 	int c;
3477836SJohn.Forte@Sun.COM 	int error;
3487836SJohn.Forte@Sun.COM 	short user_dflags = 0;
3497836SJohn.Forte@Sun.COM 	short user_rflags = 0;
3507836SJohn.Forte@Sun.COM 
3517836SJohn.Forte@Sun.COM 	/* Parse command line */
3527836SJohn.Forte@Sun.COM 	while ((c = getopt(argc, argv, "d:fFhm:r:s:z")) != EOF) {
3537836SJohn.Forte@Sun.COM 		switch (c) {
3547836SJohn.Forte@Sun.COM 			case 'd':	/* what to display */
3557836SJohn.Forte@Sun.COM 				user_dflags = set_dflags(optarg);
3567836SJohn.Forte@Sun.COM 				break;
3577836SJohn.Forte@Sun.COM 			case 'f':
3587836SJohn.Forte@Sun.COM 				hflags = HEADERS_ATT;
3597836SJohn.Forte@Sun.COM 				break;
3607836SJohn.Forte@Sun.COM 			case 'F':
3617836SJohn.Forte@Sun.COM 				hflags = HEADERS_BOR;
3627836SJohn.Forte@Sun.COM 				break;
3637836SJohn.Forte@Sun.COM 			case 'h':		/* usage */
3647836SJohn.Forte@Sun.COM 				help();
3657836SJohn.Forte@Sun.COM 				exit(0);
3667836SJohn.Forte@Sun.COM 				break;
3677836SJohn.Forte@Sun.COM 			case 'm':		/* Mode */
3687836SJohn.Forte@Sun.COM 				mode |= set_mode(optarg);
3697836SJohn.Forte@Sun.COM 				break;
3707836SJohn.Forte@Sun.COM 			case 'r':		/* what to report on */
3717836SJohn.Forte@Sun.COM 				user_rflags = set_rflags(optarg);
3727836SJohn.Forte@Sun.COM 				break;
3737836SJohn.Forte@Sun.COM 			case 's':
3747836SJohn.Forte@Sun.COM 				set_vol_list(optarg);
3757836SJohn.Forte@Sun.COM 				break;
3767836SJohn.Forte@Sun.COM 			case 'z':
3777836SJohn.Forte@Sun.COM 				zflag = 1;
3787836SJohn.Forte@Sun.COM 				break;
3797836SJohn.Forte@Sun.COM 
3807836SJohn.Forte@Sun.COM 			default:
3817836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
3827836SJohn.Forte@Sun.COM 				    "Invalid argument specified\n");
3837836SJohn.Forte@Sun.COM 		}
3847836SJohn.Forte@Sun.COM 	}
3857836SJohn.Forte@Sun.COM 
3867836SJohn.Forte@Sun.COM 	/* Parse additional arguments */
3877836SJohn.Forte@Sun.COM 	if (optind < argc) {
3887836SJohn.Forte@Sun.COM 		if ((interval = atoi(argv[optind])) <= 0) {
3897836SJohn.Forte@Sun.COM 			fail(DSSTAT_EINVAL,
3907836SJohn.Forte@Sun.COM 			    gettext("Invalid interval specified.\n"));
3917836SJohn.Forte@Sun.COM 		} else {
3927836SJohn.Forte@Sun.COM 			iterations = -1;
3937836SJohn.Forte@Sun.COM 		}
3947836SJohn.Forte@Sun.COM 
3957836SJohn.Forte@Sun.COM 		optind++;
3967836SJohn.Forte@Sun.COM 
3977836SJohn.Forte@Sun.COM 		if (optind < argc) {
3987836SJohn.Forte@Sun.COM 			if ((iterations = atoi(argv[optind])) <= 0) {
3997836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
4007836SJohn.Forte@Sun.COM 				    gettext("Invalid count specified.\n"));
4017836SJohn.Forte@Sun.COM 			}
4027836SJohn.Forte@Sun.COM 		}
4037836SJohn.Forte@Sun.COM 
4047836SJohn.Forte@Sun.COM 		optind++;
4057836SJohn.Forte@Sun.COM 	}
4067836SJohn.Forte@Sun.COM 
4077836SJohn.Forte@Sun.COM 	if (optind < argc) {
4087836SJohn.Forte@Sun.COM 		fail(DSSTAT_EINVAL,
4097836SJohn.Forte@Sun.COM 		    gettext("Too many parameters specified.\n"));
4107836SJohn.Forte@Sun.COM 	}
4117836SJohn.Forte@Sun.COM 
4127836SJohn.Forte@Sun.COM 	if (mode == 0)
4137836SJohn.Forte@Sun.COM 		mode |= MULTI | IIMG | SNDR | SDBC;
4147836SJohn.Forte@Sun.COM 
4157836SJohn.Forte@Sun.COM 	/* Select statistics to gather */
4167836SJohn.Forte@Sun.COM 	if (mode & SNDR) {
4177836SJohn.Forte@Sun.COM 		if (! (mode & MULTI)) {
4187836SJohn.Forte@Sun.COM 			if (user_rflags & IIMG_BMP)
4197836SJohn.Forte@Sun.COM 				user_rflags ^= IIMG_BMP;
4207836SJohn.Forte@Sun.COM 
4217836SJohn.Forte@Sun.COM 			if ((user_dflags | SNDR_DIS_MASK) != SNDR_DIS_MASK) {
4227836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL, gettext("Invalid "
4237836SJohn.Forte@Sun.COM 				    "display-flags for RemoteMirror\n"));
4247836SJohn.Forte@Sun.COM 			}
4257836SJohn.Forte@Sun.COM 
4267836SJohn.Forte@Sun.COM 			if ((user_rflags | SNDR_REP_MASK) != SNDR_REP_MASK) {
4277836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
4287836SJohn.Forte@Sun.COM 				    gettext("Invalid report-flags for "
429*11576SSurya.Prakki@Sun.COM 				    "Remote Mirror\n"));
4307836SJohn.Forte@Sun.COM 			}
4317836SJohn.Forte@Sun.COM 		}
4327836SJohn.Forte@Sun.COM 
4337836SJohn.Forte@Sun.COM 		if ((mode & MULTI) && (user_dflags & ASYNC_QUEUE)) {
4347836SJohn.Forte@Sun.COM 			fail(DSSTAT_EINVAL, gettext("Remote Mirror async. queue"
4357836SJohn.Forte@Sun.COM 			    "statistics can not be displayed with mutiple "
4367836SJohn.Forte@Sun.COM 			    "modes."));
4377836SJohn.Forte@Sun.COM 		}
4387836SJohn.Forte@Sun.COM 
4397836SJohn.Forte@Sun.COM 		if (user_dflags)
4407836SJohn.Forte@Sun.COM 			dflags = user_dflags;
4417836SJohn.Forte@Sun.COM 		else
4427836SJohn.Forte@Sun.COM 			dflags |= (SUMMARY | PCTS | FLAGS | RATIO);
4437836SJohn.Forte@Sun.COM 
4447836SJohn.Forte@Sun.COM 		if (user_rflags)
4457836SJohn.Forte@Sun.COM 			rflags = user_rflags;
4467836SJohn.Forte@Sun.COM 		else
4477836SJohn.Forte@Sun.COM 			rflags |= (SNDR_NET | SNDR_BMP);
4487836SJohn.Forte@Sun.COM 	}
4497836SJohn.Forte@Sun.COM 
4507836SJohn.Forte@Sun.COM 	if (mode & IIMG) {
4517836SJohn.Forte@Sun.COM 		if (! (mode & MULTI)) {
4527836SJohn.Forte@Sun.COM 			if (user_rflags & SNDR_BMP)
4537836SJohn.Forte@Sun.COM 				user_rflags ^= SNDR_BMP;
4547836SJohn.Forte@Sun.COM 
4557836SJohn.Forte@Sun.COM 			if ((user_dflags | IIMG_DIS_MASK) != IIMG_DIS_MASK) {
4567836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
4577836SJohn.Forte@Sun.COM 				    gettext("Invalid display-flags for "
458*11576SSurya.Prakki@Sun.COM 				    "Point-in-Time Copy\n"));
4597836SJohn.Forte@Sun.COM 			}
4607836SJohn.Forte@Sun.COM 
4617836SJohn.Forte@Sun.COM 			if ((user_rflags | IIMG_REP_MASK) != IIMG_REP_MASK) {
4627836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL,
4637836SJohn.Forte@Sun.COM 				    gettext("Invalid report-flags for "
464*11576SSurya.Prakki@Sun.COM 				    "Point-in-Time Copy\n"));
4657836SJohn.Forte@Sun.COM 			}
4667836SJohn.Forte@Sun.COM 		}
4677836SJohn.Forte@Sun.COM 
4687836SJohn.Forte@Sun.COM 		if (user_dflags)
4697836SJohn.Forte@Sun.COM 			dflags = user_dflags;
4707836SJohn.Forte@Sun.COM 		else
4717836SJohn.Forte@Sun.COM 			dflags |= (SUMMARY | PCTS | FLAGS | RATIO);
4727836SJohn.Forte@Sun.COM 
4737836SJohn.Forte@Sun.COM 		if (user_rflags)
4747836SJohn.Forte@Sun.COM 			rflags = user_rflags;
4757836SJohn.Forte@Sun.COM 		else
4767836SJohn.Forte@Sun.COM 			rflags |= (IIMG_MST | IIMG_SHD | IIMG_BMP | IIMG_OVR);
4777836SJohn.Forte@Sun.COM 	}
4787836SJohn.Forte@Sun.COM 
4797836SJohn.Forte@Sun.COM 	if (mode & SDBC) {
4807836SJohn.Forte@Sun.COM 		if (! (mode & MULTI)) {
4817836SJohn.Forte@Sun.COM 			if ((user_dflags | CACHE_DIS_MASK) != CACHE_DIS_MASK) {
4827836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL, gettext("Invalid "
4837836SJohn.Forte@Sun.COM 				    "display-flags for CACHE\n"));
4847836SJohn.Forte@Sun.COM 			}
4857836SJohn.Forte@Sun.COM 
4867836SJohn.Forte@Sun.COM 			if ((user_rflags | CACHE_REP_MASK) != CACHE_REP_MASK) {
4877836SJohn.Forte@Sun.COM 				fail(DSSTAT_EINVAL, gettext("Invalid "
4887836SJohn.Forte@Sun.COM 				    "report-flags for CACHE\n"));
4897836SJohn.Forte@Sun.COM 			}
4907836SJohn.Forte@Sun.COM 		} else {
4917836SJohn.Forte@Sun.COM 		    if ((user_dflags & DESTAGED) || (user_dflags & WRCANCEL)) {
4927836SJohn.Forte@Sun.COM 			if (user_dflags & DESTAGED)
4937836SJohn.Forte@Sun.COM 			    fail(DSSTAT_EINVAL, gettext("Cache, destaged "
4947836SJohn.Forte@Sun.COM 				"statistics can not be displayed with mutiple "
4957836SJohn.Forte@Sun.COM 				"modes."));
4967836SJohn.Forte@Sun.COM 			else
4977836SJohn.Forte@Sun.COM 			    fail(DSSTAT_EINVAL, gettext("Cache, write "
4987836SJohn.Forte@Sun.COM 				"cancellations "
4997836SJohn.Forte@Sun.COM 				"statistics can not be displayed with mutiple "
5007836SJohn.Forte@Sun.COM 				"modes."));
5017836SJohn.Forte@Sun.COM 		    }
5027836SJohn.Forte@Sun.COM 		}
5037836SJohn.Forte@Sun.COM 
5047836SJohn.Forte@Sun.COM 		if (user_dflags)
5057836SJohn.Forte@Sun.COM 			dflags = user_dflags;
5067836SJohn.Forte@Sun.COM 		else
5077836SJohn.Forte@Sun.COM 			if (mode & MULTI)
5087836SJohn.Forte@Sun.COM 				dflags |= (SUMMARY);
5097836SJohn.Forte@Sun.COM 			else
5107836SJohn.Forte@Sun.COM 				dflags |= (SUMMARY | FLAGS);
5117836SJohn.Forte@Sun.COM 
5127836SJohn.Forte@Sun.COM 		if (user_rflags)
5137836SJohn.Forte@Sun.COM 			rflags = user_rflags;
5147836SJohn.Forte@Sun.COM 		else
5157836SJohn.Forte@Sun.COM 			rflags |= user_rflags;
5167836SJohn.Forte@Sun.COM 	}
5177836SJohn.Forte@Sun.COM 
5187836SJohn.Forte@Sun.COM 	error = do_stats();
5197836SJohn.Forte@Sun.COM 
5207836SJohn.Forte@Sun.COM 	if (error == EAGAIN) {
5217836SJohn.Forte@Sun.COM 		fail(DSSTAT_NOSTAT, gettext("No statistics available for the "
5227836SJohn.Forte@Sun.COM 		    "specified mode(s).\n"));
5237836SJohn.Forte@Sun.COM 	}
5247836SJohn.Forte@Sun.COM 
5257836SJohn.Forte@Sun.COM 	if (error == EINVAL) {
5267836SJohn.Forte@Sun.COM 		fail(DSSTAT_EINVAL,
5277836SJohn.Forte@Sun.COM 		    gettext("Invalid kstat format detected.\n"));
5287836SJohn.Forte@Sun.COM 	}
5297836SJohn.Forte@Sun.COM 
5307836SJohn.Forte@Sun.COM 	if (error == ENOMEM) {
5317836SJohn.Forte@Sun.COM 		fail(DSSTAT_ENOMEM,
5327836SJohn.Forte@Sun.COM 		    gettext("Unable to open kstat device for reading.\n"));
5337836SJohn.Forte@Sun.COM 	}
5347836SJohn.Forte@Sun.COM 
5357836SJohn.Forte@Sun.COM 	if (error == -1) {
5367836SJohn.Forte@Sun.COM 		if (execv("/usr/sbin/dsstat", argv) != 0) {
5377836SJohn.Forte@Sun.COM 			fail(DSSTAT_EMAP, gettext("Kstat is invalid.\n"));
5387836SJohn.Forte@Sun.COM 		}
5397836SJohn.Forte@Sun.COM 	}
5407836SJohn.Forte@Sun.COM 
5417836SJohn.Forte@Sun.COM 	if (error) {
5427836SJohn.Forte@Sun.COM 		fail(DSSTAT_EUNKNWN, gettext("An unknown error occured.\n"));
5437836SJohn.Forte@Sun.COM 	}
5447836SJohn.Forte@Sun.COM 
5457836SJohn.Forte@Sun.COM 	return (0);
5467836SJohn.Forte@Sun.COM }
547