xref: /titanic_54/usr/src/cmd/avs/dsstat/dsstat.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte #include <stdio.h>
27*fcf3ce44SJohn Forte #include <stdlib.h>
28*fcf3ce44SJohn Forte #include <string.h>
29*fcf3ce44SJohn Forte #include <unistd.h>
30*fcf3ce44SJohn Forte #include <errno.h>
31*fcf3ce44SJohn Forte #include <inttypes.h>
32*fcf3ce44SJohn Forte #include <locale.h>
33*fcf3ce44SJohn Forte 
34*fcf3ce44SJohn Forte #include <kstat.h>
35*fcf3ce44SJohn Forte 
36*fcf3ce44SJohn Forte #include "dsstat.h"
37*fcf3ce44SJohn Forte #include "multi_stats.h"
38*fcf3ce44SJohn Forte 
39*fcf3ce44SJohn Forte /* Globals */
40*fcf3ce44SJohn Forte int mode = 0;
41*fcf3ce44SJohn Forte int interval = 1;
42*fcf3ce44SJohn Forte int iterations = 1;
43*fcf3ce44SJohn Forte int zflag = 0;
44*fcf3ce44SJohn Forte int linesout = 0;
45*fcf3ce44SJohn Forte 
46*fcf3ce44SJohn Forte short hflags = HEADERS_EXL;
47*fcf3ce44SJohn Forte short dflags = 0;
48*fcf3ce44SJohn Forte short rflags = 0;
49*fcf3ce44SJohn Forte vslist_t *vs_top = NULL;
50*fcf3ce44SJohn Forte 
51*fcf3ce44SJohn Forte void
52*fcf3ce44SJohn Forte errout(char *msg)
53*fcf3ce44SJohn Forte {
54*fcf3ce44SJohn Forte 
55*fcf3ce44SJohn Forte 	(void) fprintf(stderr, msg);
56*fcf3ce44SJohn Forte }
57*fcf3ce44SJohn Forte 
58*fcf3ce44SJohn Forte void
59*fcf3ce44SJohn Forte usage()
60*fcf3ce44SJohn Forte {
61*fcf3ce44SJohn Forte 	errout(gettext(
62*fcf3ce44SJohn Forte 	    "\ndsstat [-m <mode>[,<mode>]] [-f | -F] [-z] [-s <sets>] "
63*fcf3ce44SJohn Forte 	    "[-r <flags>] \\\n[-d <flags>] [<interval> [<count>]]\n\n"));
64*fcf3ce44SJohn Forte }
65*fcf3ce44SJohn Forte 
66*fcf3ce44SJohn Forte void
67*fcf3ce44SJohn Forte help()
68*fcf3ce44SJohn Forte {
69*fcf3ce44SJohn Forte 	usage();
70*fcf3ce44SJohn Forte 
71*fcf3ce44SJohn Forte 	errout(gettext("\t"
72*fcf3ce44SJohn Forte 	    "-d <flags> Specifies the statistics to be displayed\n\n"));
73*fcf3ce44SJohn Forte 	errout(gettext("\t"
74*fcf3ce44SJohn Forte 	    "   For 'cache' mode\n"));
75*fcf3ce44SJohn Forte 	errout(gettext("\t"
76*fcf3ce44SJohn Forte 	    "      Valid <flags> are 'rwfsdc', default <flags> are 'sf'\n"));
77*fcf3ce44SJohn Forte 	errout(gettext("\t"
78*fcf3ce44SJohn Forte 	    "      r=read, w=write, f=flags, s=summary,\n"));
79*fcf3ce44SJohn Forte 	errout(gettext("\t"
80*fcf3ce44SJohn Forte 	    "   only available for cache mode, need to combine with '-m'\n"));
81*fcf3ce44SJohn Forte 	errout(gettext("\t"
82*fcf3ce44SJohn Forte 	    "      d=destaged, c=write cancellations\n\n"));
83*fcf3ce44SJohn Forte 	errout(gettext("\t"
84*fcf3ce44SJohn Forte 	    "   For 'ii' mode;\n"));
85*fcf3ce44SJohn Forte 	errout(gettext("\t"
86*fcf3ce44SJohn Forte 	    "      Valid <flags> are 'rwtfps', default <flags> are 'sf'\n"));
87*fcf3ce44SJohn Forte 	errout(gettext("\t"
88*fcf3ce44SJohn Forte 	    "      r=read, w=write, t=timing, f=flags, p=percentages,\n"));
89*fcf3ce44SJohn Forte 	errout(gettext("\t"
90*fcf3ce44SJohn Forte 	    "      s=summary\n\n"));
91*fcf3ce44SJohn Forte 	errout(gettext("\t"
92*fcf3ce44SJohn Forte 	    "   For 'sndr' mode;\n"));
93*fcf3ce44SJohn Forte 	errout(gettext("\t"
94*fcf3ce44SJohn Forte 	    "      Valid <flags> are'rwtfpsq', default <flags> are 'spf'\n"));
95*fcf3ce44SJohn Forte 	errout(gettext("\t"
96*fcf3ce44SJohn Forte 	    "      r=read, w=write, t=timing, f=flags, p=percentages,\n"));
97*fcf3ce44SJohn Forte 	errout(gettext("\t"
98*fcf3ce44SJohn Forte 	    "      s=summary\n"));
99*fcf3ce44SJohn Forte 	errout(gettext("\t"
100*fcf3ce44SJohn Forte 	    "   only available for sndr mode, need to combine with '-m'\n"));
101*fcf3ce44SJohn Forte 	errout(gettext("\t"
102*fcf3ce44SJohn Forte 	    "      q=queue\n\n"));
103*fcf3ce44SJohn Forte 	errout(gettext("\t"
104*fcf3ce44SJohn Forte 	    "-f  prints field headers once for each iteration\n\n"));
105*fcf3ce44SJohn Forte 	errout(gettext("\t"
106*fcf3ce44SJohn Forte 	    "-F  prints field headers once, at the start of reporting\n\n"));
107*fcf3ce44SJohn Forte 	errout(gettext("\t"
108*fcf3ce44SJohn Forte 	    "-h  prints detailed usage message\n\n"));
109*fcf3ce44SJohn Forte 	errout(gettext("\t"
110*fcf3ce44SJohn Forte 	    "-m <mode>[,<mode>] where mode is, 'cache', 'ii', or 'sndr'\n\n"));
111*fcf3ce44SJohn Forte 	errout(gettext("\t"
112*fcf3ce44SJohn Forte 	    "   Multiple modes may be specified as a comma separated list,\n"));
113*fcf3ce44SJohn Forte 	errout(gettext("\t"
114*fcf3ce44SJohn Forte 	    "   or multiple -m switches may be used.\n\n"));
115*fcf3ce44SJohn Forte 	errout(gettext("\t"
116*fcf3ce44SJohn Forte 	    "-r <flags> specifies components to be reported\n\n"));
117*fcf3ce44SJohn Forte 	errout(gettext("\t"
118*fcf3ce44SJohn Forte 	    "   For 'cache' mode, this option is not used.\n\n"));
119*fcf3ce44SJohn Forte 	errout(gettext("\t"
120*fcf3ce44SJohn Forte 	    "   For 'ii' mode;\n"));
121*fcf3ce44SJohn Forte 	errout(gettext("\t"
122*fcf3ce44SJohn Forte 	    "      Valid <flags> are 'msbo', default <flags> are 'msbo'\n"));
123*fcf3ce44SJohn Forte 	errout(gettext("\t"
124*fcf3ce44SJohn Forte 	    "      m=master, s=shadow, b=bitmap, o=overflow\n\n"));
125*fcf3ce44SJohn Forte 	errout(gettext("\t"
126*fcf3ce44SJohn Forte 	    "   For 'sndr' mode;\n"));
127*fcf3ce44SJohn Forte 	errout(gettext("\t"
128*fcf3ce44SJohn Forte 	    "      Valid <flags> are 'nb', default <flags> are 'nb'\n"));
129*fcf3ce44SJohn Forte 	errout(gettext("\t"
130*fcf3ce44SJohn Forte 	    "      n=network, b=bitmap\n\n"));
131*fcf3ce44SJohn Forte 	errout(gettext("\t"
132*fcf3ce44SJohn Forte 	    "-s <sets> outputs specified sets\n"));
133*fcf3ce44SJohn Forte 	errout(gettext("\t"
134*fcf3ce44SJohn Forte 	    "    Where <sets> is a comma delimited list of set names\n\n"));
135*fcf3ce44SJohn Forte 	errout(gettext("\t"
136*fcf3ce44SJohn Forte 	    "-z  suppress reports with zero value (no activity)\n\n"));
137*fcf3ce44SJohn Forte 	errout(gettext("\t"
138*fcf3ce44SJohn Forte 	    "<interval> is the number of seconds between reports\n\n"));
139*fcf3ce44SJohn Forte 	errout(gettext("\t"
140*fcf3ce44SJohn Forte 	    "<count> is the number of reports to be generated\n\n"));
141*fcf3ce44SJohn Forte }
142*fcf3ce44SJohn Forte 
143*fcf3ce44SJohn Forte void
144*fcf3ce44SJohn Forte fail(int err, char *msg)
145*fcf3ce44SJohn Forte {
146*fcf3ce44SJohn Forte 	errout(gettext("\ndsstat: "));
147*fcf3ce44SJohn Forte 	errout(msg);
148*fcf3ce44SJohn Forte 
149*fcf3ce44SJohn Forte 	usage();
150*fcf3ce44SJohn Forte 
151*fcf3ce44SJohn Forte 	errout(gettext("For detailed usage run \"dsstat -h\"\n"));
152*fcf3ce44SJohn Forte 
153*fcf3ce44SJohn Forte 	exit(err);
154*fcf3ce44SJohn Forte }
155*fcf3ce44SJohn Forte 
156*fcf3ce44SJohn Forte int
157*fcf3ce44SJohn Forte set_mode(char *user_modes)
158*fcf3ce44SJohn Forte {
159*fcf3ce44SJohn Forte 	char *m;
160*fcf3ce44SJohn Forte 	int local_mode = 0;
161*fcf3ce44SJohn Forte 
162*fcf3ce44SJohn Forte 	for (m = strtok(user_modes, ","); m != NULL; m = strtok(NULL, ",")) {
163*fcf3ce44SJohn Forte 		if (local_mode != 0) {
164*fcf3ce44SJohn Forte 			local_mode |= MULTI;
165*fcf3ce44SJohn Forte 		}
166*fcf3ce44SJohn Forte 
167*fcf3ce44SJohn Forte 		if (strncasecmp("sndr", m, strlen(m)) == 0) {
168*fcf3ce44SJohn Forte 			local_mode |= SNDR;
169*fcf3ce44SJohn Forte 			continue;
170*fcf3ce44SJohn Forte 		}
171*fcf3ce44SJohn Forte 
172*fcf3ce44SJohn Forte 		if (strncasecmp("ii", m, strlen(m)) == 0) {
173*fcf3ce44SJohn Forte 			local_mode |= IIMG;
174*fcf3ce44SJohn Forte 			continue;
175*fcf3ce44SJohn Forte 		}
176*fcf3ce44SJohn Forte 
177*fcf3ce44SJohn Forte 		if (strncasecmp("cache", m, strlen(m)) == 0) {
178*fcf3ce44SJohn Forte 			local_mode |= SDBC;
179*fcf3ce44SJohn Forte 			continue;
180*fcf3ce44SJohn Forte 		}
181*fcf3ce44SJohn Forte 
182*fcf3ce44SJohn Forte 		fail(DSSTAT_EINVAL, gettext("Invalid mode specified"));
183*fcf3ce44SJohn Forte 	}
184*fcf3ce44SJohn Forte 
185*fcf3ce44SJohn Forte 	return (local_mode);
186*fcf3ce44SJohn Forte }
187*fcf3ce44SJohn Forte 
188*fcf3ce44SJohn Forte short
189*fcf3ce44SJohn Forte set_dflags(char *flags)
190*fcf3ce44SJohn Forte {
191*fcf3ce44SJohn Forte 	int index;
192*fcf3ce44SJohn Forte 	short user_dflags = 0;
193*fcf3ce44SJohn Forte 
194*fcf3ce44SJohn Forte 	for (index = 0; index < strlen(flags); index++) {
195*fcf3ce44SJohn Forte 		switch (flags[index]) {
196*fcf3ce44SJohn Forte 			case 'r':
197*fcf3ce44SJohn Forte 				user_dflags |= READ;
198*fcf3ce44SJohn Forte 				break;
199*fcf3ce44SJohn Forte 			case 'w':
200*fcf3ce44SJohn Forte 				user_dflags |= WRITE;
201*fcf3ce44SJohn Forte 				break;
202*fcf3ce44SJohn Forte 			case 't':
203*fcf3ce44SJohn Forte 				user_dflags |= TIMING;
204*fcf3ce44SJohn Forte 				break;
205*fcf3ce44SJohn Forte 			case 'f':
206*fcf3ce44SJohn Forte 				user_dflags |= FLAGS;
207*fcf3ce44SJohn Forte 				break;
208*fcf3ce44SJohn Forte 			case 'p':
209*fcf3ce44SJohn Forte 				user_dflags |= PCTS;
210*fcf3ce44SJohn Forte 				break;
211*fcf3ce44SJohn Forte 			case 's':
212*fcf3ce44SJohn Forte 				user_dflags |= SUMMARY;
213*fcf3ce44SJohn Forte 				break;
214*fcf3ce44SJohn Forte 			case 'd':
215*fcf3ce44SJohn Forte 				user_dflags |= DESTAGED;
216*fcf3ce44SJohn Forte 				break;
217*fcf3ce44SJohn Forte 			case 'c':
218*fcf3ce44SJohn Forte 				user_dflags |= WRCANCEL;
219*fcf3ce44SJohn Forte 				break;
220*fcf3ce44SJohn Forte 			case 'h':
221*fcf3ce44SJohn Forte 				user_dflags |= RATIO;
222*fcf3ce44SJohn Forte 				break;
223*fcf3ce44SJohn Forte 			case 'q':
224*fcf3ce44SJohn Forte 				user_dflags |= ASYNC_QUEUE;
225*fcf3ce44SJohn Forte 				break;
226*fcf3ce44SJohn Forte 			default:
227*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
228*fcf3ce44SJohn Forte 				    gettext("Invalid display-flags set\n"));
229*fcf3ce44SJohn Forte 		}
230*fcf3ce44SJohn Forte 	}
231*fcf3ce44SJohn Forte 
232*fcf3ce44SJohn Forte 	return (user_dflags);
233*fcf3ce44SJohn Forte }
234*fcf3ce44SJohn Forte 
235*fcf3ce44SJohn Forte short
236*fcf3ce44SJohn Forte set_rflags(char *flags)
237*fcf3ce44SJohn Forte {
238*fcf3ce44SJohn Forte 	int index;
239*fcf3ce44SJohn Forte 	short user_rflags = 0;
240*fcf3ce44SJohn Forte 
241*fcf3ce44SJohn Forte 	for (index = 0; index < strlen(flags); index++) {
242*fcf3ce44SJohn Forte 		switch (flags[index]) {
243*fcf3ce44SJohn Forte 			case 'm':
244*fcf3ce44SJohn Forte 				user_rflags |= IIMG_MST;
245*fcf3ce44SJohn Forte 				break;
246*fcf3ce44SJohn Forte 			case 's':
247*fcf3ce44SJohn Forte 				user_rflags |= IIMG_SHD;
248*fcf3ce44SJohn Forte 				break;
249*fcf3ce44SJohn Forte 			case 'b':
250*fcf3ce44SJohn Forte 				user_rflags |= IIMG_BMP;
251*fcf3ce44SJohn Forte 				user_rflags |= SNDR_BMP;
252*fcf3ce44SJohn Forte 				break;
253*fcf3ce44SJohn Forte 			case 'o':
254*fcf3ce44SJohn Forte 				user_rflags |= IIMG_OVR;
255*fcf3ce44SJohn Forte 				break;
256*fcf3ce44SJohn Forte 			case 'n':
257*fcf3ce44SJohn Forte 				user_rflags |= SNDR_NET;
258*fcf3ce44SJohn Forte 				break;
259*fcf3ce44SJohn Forte 			default:
260*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
261*fcf3ce44SJohn Forte 				    gettext("Invalid report-flags set\n"));
262*fcf3ce44SJohn Forte 		}
263*fcf3ce44SJohn Forte 	}
264*fcf3ce44SJohn Forte 
265*fcf3ce44SJohn Forte 	return (user_rflags);
266*fcf3ce44SJohn Forte }
267*fcf3ce44SJohn Forte 
268*fcf3ce44SJohn Forte void
269*fcf3ce44SJohn Forte set_vol_list(char *list)
270*fcf3ce44SJohn Forte {
271*fcf3ce44SJohn Forte 	vslist_t *pre;
272*fcf3ce44SJohn Forte 	vslist_t *newvol;
273*fcf3ce44SJohn Forte 	vslist_t *vslist;
274*fcf3ce44SJohn Forte 	char *volume;
275*fcf3ce44SJohn Forte 
276*fcf3ce44SJohn Forte 	for (volume = strtok(list, ","); volume != NULL;
277*fcf3ce44SJohn Forte 	    volume = strtok(NULL, ",")) {
278*fcf3ce44SJohn Forte 		int dup = 0;
279*fcf3ce44SJohn Forte 		char *vh = NULL;
280*fcf3ce44SJohn Forte 		char *vn = NULL;
281*fcf3ce44SJohn Forte 
282*fcf3ce44SJohn Forte 		/* get user-specified set information */
283*fcf3ce44SJohn Forte 		if ((vn = strchr(volume, ':')) == NULL) {
284*fcf3ce44SJohn Forte 			vn = volume;
285*fcf3ce44SJohn Forte 		} else {
286*fcf3ce44SJohn Forte 			*vn = '\0';
287*fcf3ce44SJohn Forte 			vn++;
288*fcf3ce44SJohn Forte 			vh = volume;
289*fcf3ce44SJohn Forte 		}
290*fcf3ce44SJohn Forte 
291*fcf3ce44SJohn Forte 		/* check for duplicates */
292*fcf3ce44SJohn Forte 		dup = 0;
293*fcf3ce44SJohn Forte 
294*fcf3ce44SJohn Forte 		for (vslist = vs_top; vslist != NULL; vslist = vslist->next) {
295*fcf3ce44SJohn Forte 			if (vslist->volhost && vh) {
296*fcf3ce44SJohn Forte 				if (strcmp(vslist->volhost, vh) == 0 &&
297*fcf3ce44SJohn Forte 				    strcmp(vslist->volname, vn) == 0)
298*fcf3ce44SJohn Forte 					dup = 1;
299*fcf3ce44SJohn Forte 			} else {
300*fcf3ce44SJohn Forte 				if (strcmp(vslist->volname, vn) == 0)
301*fcf3ce44SJohn Forte 					dup = 1;
302*fcf3ce44SJohn Forte 			}
303*fcf3ce44SJohn Forte 
304*fcf3ce44SJohn Forte 			pre = vslist;
305*fcf3ce44SJohn Forte 		}
306*fcf3ce44SJohn Forte 
307*fcf3ce44SJohn Forte 		if (dup)
308*fcf3ce44SJohn Forte 			continue;
309*fcf3ce44SJohn Forte 
310*fcf3ce44SJohn Forte 		/* initialize new vslist record */
311*fcf3ce44SJohn Forte 		newvol = (vslist_t *)calloc(1, sizeof (vslist_t));
312*fcf3ce44SJohn Forte 
313*fcf3ce44SJohn Forte 		newvol->volname = (char *)calloc((strlen(vn) + 1),
314*fcf3ce44SJohn Forte 			sizeof (char));
315*fcf3ce44SJohn Forte 		strcpy(newvol->volname, vn);
316*fcf3ce44SJohn Forte 
317*fcf3ce44SJohn Forte 		if (vh == NULL)
318*fcf3ce44SJohn Forte 			goto save;
319*fcf3ce44SJohn Forte 
320*fcf3ce44SJohn Forte 		newvol->volhost = (char *)calloc((strlen(vh) + 1),
321*fcf3ce44SJohn Forte 			sizeof (char));
322*fcf3ce44SJohn Forte 		strcpy(newvol->volhost, vh);
323*fcf3ce44SJohn Forte 
324*fcf3ce44SJohn Forte save:
325*fcf3ce44SJohn Forte 		/* save record */
326*fcf3ce44SJohn Forte 		if (vs_top == NULL) {
327*fcf3ce44SJohn Forte 			vslist = vs_top = newvol;
328*fcf3ce44SJohn Forte 			vslist->next = NULL;
329*fcf3ce44SJohn Forte 			continue;
330*fcf3ce44SJohn Forte 		}
331*fcf3ce44SJohn Forte 
332*fcf3ce44SJohn Forte 		if (vslist == NULL) {
333*fcf3ce44SJohn Forte 			vslist = pre->next = newvol;
334*fcf3ce44SJohn Forte 			vslist->next = NULL;
335*fcf3ce44SJohn Forte 			continue;
336*fcf3ce44SJohn Forte 		}
337*fcf3ce44SJohn Forte 	}
338*fcf3ce44SJohn Forte }
339*fcf3ce44SJohn Forte 
340*fcf3ce44SJohn Forte int
341*fcf3ce44SJohn Forte main(int argc, char **argv)
342*fcf3ce44SJohn Forte {
343*fcf3ce44SJohn Forte 	extern char *optarg;
344*fcf3ce44SJohn Forte 	extern int optind;
345*fcf3ce44SJohn Forte 
346*fcf3ce44SJohn Forte 	int c;
347*fcf3ce44SJohn Forte 	int error;
348*fcf3ce44SJohn Forte 	short user_dflags = 0;
349*fcf3ce44SJohn Forte 	short user_rflags = 0;
350*fcf3ce44SJohn Forte 
351*fcf3ce44SJohn Forte 	/* Parse command line */
352*fcf3ce44SJohn Forte 	while ((c = getopt(argc, argv, "d:fFhm:r:s:z")) != EOF) {
353*fcf3ce44SJohn Forte 		switch (c) {
354*fcf3ce44SJohn Forte 			case 'd':	/* what to display */
355*fcf3ce44SJohn Forte 				user_dflags = set_dflags(optarg);
356*fcf3ce44SJohn Forte 				break;
357*fcf3ce44SJohn Forte 			case 'f':
358*fcf3ce44SJohn Forte 				hflags = HEADERS_ATT;
359*fcf3ce44SJohn Forte 				break;
360*fcf3ce44SJohn Forte 			case 'F':
361*fcf3ce44SJohn Forte 				hflags = HEADERS_BOR;
362*fcf3ce44SJohn Forte 				break;
363*fcf3ce44SJohn Forte 			case 'h':		/* usage */
364*fcf3ce44SJohn Forte 				help();
365*fcf3ce44SJohn Forte 				exit(0);
366*fcf3ce44SJohn Forte 				break;
367*fcf3ce44SJohn Forte 			case 'm':		/* Mode */
368*fcf3ce44SJohn Forte 				mode |= set_mode(optarg);
369*fcf3ce44SJohn Forte 				break;
370*fcf3ce44SJohn Forte 			case 'r':		/* what to report on */
371*fcf3ce44SJohn Forte 				user_rflags = set_rflags(optarg);
372*fcf3ce44SJohn Forte 				break;
373*fcf3ce44SJohn Forte 			case 's':
374*fcf3ce44SJohn Forte 				set_vol_list(optarg);
375*fcf3ce44SJohn Forte 				break;
376*fcf3ce44SJohn Forte 			case 'z':
377*fcf3ce44SJohn Forte 				zflag = 1;
378*fcf3ce44SJohn Forte 				break;
379*fcf3ce44SJohn Forte 
380*fcf3ce44SJohn Forte 			default:
381*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
382*fcf3ce44SJohn Forte 				    "Invalid argument specified\n");
383*fcf3ce44SJohn Forte 		}
384*fcf3ce44SJohn Forte 	}
385*fcf3ce44SJohn Forte 
386*fcf3ce44SJohn Forte 	/* Parse additional arguments */
387*fcf3ce44SJohn Forte 	if (optind < argc) {
388*fcf3ce44SJohn Forte 		if ((interval = atoi(argv[optind])) <= 0) {
389*fcf3ce44SJohn Forte 			fail(DSSTAT_EINVAL,
390*fcf3ce44SJohn Forte 			    gettext("Invalid interval specified.\n"));
391*fcf3ce44SJohn Forte 		} else {
392*fcf3ce44SJohn Forte 			iterations = -1;
393*fcf3ce44SJohn Forte 		}
394*fcf3ce44SJohn Forte 
395*fcf3ce44SJohn Forte 		optind++;
396*fcf3ce44SJohn Forte 
397*fcf3ce44SJohn Forte 		if (optind < argc) {
398*fcf3ce44SJohn Forte 			if ((iterations = atoi(argv[optind])) <= 0) {
399*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
400*fcf3ce44SJohn Forte 				    gettext("Invalid count specified.\n"));
401*fcf3ce44SJohn Forte 			}
402*fcf3ce44SJohn Forte 		}
403*fcf3ce44SJohn Forte 
404*fcf3ce44SJohn Forte 		optind++;
405*fcf3ce44SJohn Forte 	}
406*fcf3ce44SJohn Forte 
407*fcf3ce44SJohn Forte 	if (optind < argc) {
408*fcf3ce44SJohn Forte 		fail(DSSTAT_EINVAL,
409*fcf3ce44SJohn Forte 		    gettext("Too many parameters specified.\n"));
410*fcf3ce44SJohn Forte 	}
411*fcf3ce44SJohn Forte 
412*fcf3ce44SJohn Forte 	if (mode == 0)
413*fcf3ce44SJohn Forte 		mode |= MULTI | IIMG | SNDR | SDBC;
414*fcf3ce44SJohn Forte 
415*fcf3ce44SJohn Forte 	/* Select statistics to gather */
416*fcf3ce44SJohn Forte 	if (mode & SNDR) {
417*fcf3ce44SJohn Forte 		if (! (mode & MULTI)) {
418*fcf3ce44SJohn Forte 			if (user_rflags & IIMG_BMP)
419*fcf3ce44SJohn Forte 				user_rflags ^= IIMG_BMP;
420*fcf3ce44SJohn Forte 
421*fcf3ce44SJohn Forte 			if ((user_dflags | SNDR_DIS_MASK) != SNDR_DIS_MASK) {
422*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL, gettext("Invalid "
423*fcf3ce44SJohn Forte 				    "display-flags for RemoteMirror\n"));
424*fcf3ce44SJohn Forte 			}
425*fcf3ce44SJohn Forte 
426*fcf3ce44SJohn Forte 			if ((user_rflags | SNDR_REP_MASK) != SNDR_REP_MASK) {
427*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
428*fcf3ce44SJohn Forte 				    gettext("Invalid report-flags for "
429*fcf3ce44SJohn Forte 					    "Remote Mirror\n"));
430*fcf3ce44SJohn Forte 			}
431*fcf3ce44SJohn Forte 		}
432*fcf3ce44SJohn Forte 
433*fcf3ce44SJohn Forte 		if ((mode & MULTI) && (user_dflags & ASYNC_QUEUE)) {
434*fcf3ce44SJohn Forte 			fail(DSSTAT_EINVAL, gettext("Remote Mirror async. queue"
435*fcf3ce44SJohn Forte 			    "statistics can not be displayed with mutiple "
436*fcf3ce44SJohn Forte 			    "modes."));
437*fcf3ce44SJohn Forte 		}
438*fcf3ce44SJohn Forte 
439*fcf3ce44SJohn Forte 		if (user_dflags)
440*fcf3ce44SJohn Forte 			dflags = user_dflags;
441*fcf3ce44SJohn Forte 		else
442*fcf3ce44SJohn Forte 			dflags |= (SUMMARY | PCTS | FLAGS | RATIO);
443*fcf3ce44SJohn Forte 
444*fcf3ce44SJohn Forte 		if (user_rflags)
445*fcf3ce44SJohn Forte 			rflags = user_rflags;
446*fcf3ce44SJohn Forte 		else
447*fcf3ce44SJohn Forte 			rflags |= (SNDR_NET | SNDR_BMP);
448*fcf3ce44SJohn Forte 	}
449*fcf3ce44SJohn Forte 
450*fcf3ce44SJohn Forte 	if (mode & IIMG) {
451*fcf3ce44SJohn Forte 		if (! (mode & MULTI)) {
452*fcf3ce44SJohn Forte 			if (user_rflags & SNDR_BMP)
453*fcf3ce44SJohn Forte 				user_rflags ^= SNDR_BMP;
454*fcf3ce44SJohn Forte 
455*fcf3ce44SJohn Forte 			if ((user_dflags | IIMG_DIS_MASK) != IIMG_DIS_MASK) {
456*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
457*fcf3ce44SJohn Forte 				    gettext("Invalid display-flags for "
458*fcf3ce44SJohn Forte 					    "Point-in-Time Copy\n"));
459*fcf3ce44SJohn Forte 			}
460*fcf3ce44SJohn Forte 
461*fcf3ce44SJohn Forte 			if ((user_rflags | IIMG_REP_MASK) != IIMG_REP_MASK) {
462*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL,
463*fcf3ce44SJohn Forte 				    gettext("Invalid report-flags for "
464*fcf3ce44SJohn Forte 					    "Point-in-Time Copy\n"));
465*fcf3ce44SJohn Forte 			}
466*fcf3ce44SJohn Forte 		}
467*fcf3ce44SJohn Forte 
468*fcf3ce44SJohn Forte 		if (user_dflags)
469*fcf3ce44SJohn Forte 			dflags = user_dflags;
470*fcf3ce44SJohn Forte 		else
471*fcf3ce44SJohn Forte 			dflags |= (SUMMARY | PCTS | FLAGS | RATIO);
472*fcf3ce44SJohn Forte 
473*fcf3ce44SJohn Forte 		if (user_rflags)
474*fcf3ce44SJohn Forte 			rflags = user_rflags;
475*fcf3ce44SJohn Forte 		else
476*fcf3ce44SJohn Forte 			rflags |= (IIMG_MST | IIMG_SHD | IIMG_BMP | IIMG_OVR);
477*fcf3ce44SJohn Forte 	}
478*fcf3ce44SJohn Forte 
479*fcf3ce44SJohn Forte 	if (mode & SDBC) {
480*fcf3ce44SJohn Forte 		if (! (mode & MULTI)) {
481*fcf3ce44SJohn Forte 			if ((user_dflags | CACHE_DIS_MASK) != CACHE_DIS_MASK) {
482*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL, gettext("Invalid "
483*fcf3ce44SJohn Forte 				    "display-flags for CACHE\n"));
484*fcf3ce44SJohn Forte 			}
485*fcf3ce44SJohn Forte 
486*fcf3ce44SJohn Forte 			if ((user_rflags | CACHE_REP_MASK) != CACHE_REP_MASK) {
487*fcf3ce44SJohn Forte 				fail(DSSTAT_EINVAL, gettext("Invalid "
488*fcf3ce44SJohn Forte 				    "report-flags for CACHE\n"));
489*fcf3ce44SJohn Forte 			}
490*fcf3ce44SJohn Forte 		} else {
491*fcf3ce44SJohn Forte 		    if ((user_dflags & DESTAGED) || (user_dflags & WRCANCEL)) {
492*fcf3ce44SJohn Forte 			if (user_dflags & DESTAGED)
493*fcf3ce44SJohn Forte 			    fail(DSSTAT_EINVAL, gettext("Cache, destaged "
494*fcf3ce44SJohn Forte 				"statistics can not be displayed with mutiple "
495*fcf3ce44SJohn Forte 				"modes."));
496*fcf3ce44SJohn Forte 			else
497*fcf3ce44SJohn Forte 			    fail(DSSTAT_EINVAL, gettext("Cache, write "
498*fcf3ce44SJohn Forte 				"cancellations "
499*fcf3ce44SJohn Forte 				"statistics can not be displayed with mutiple "
500*fcf3ce44SJohn Forte 				"modes."));
501*fcf3ce44SJohn Forte 		    }
502*fcf3ce44SJohn Forte 		}
503*fcf3ce44SJohn Forte 
504*fcf3ce44SJohn Forte 		if (user_dflags)
505*fcf3ce44SJohn Forte 			dflags = user_dflags;
506*fcf3ce44SJohn Forte 		else
507*fcf3ce44SJohn Forte 			if (mode & MULTI)
508*fcf3ce44SJohn Forte 				dflags |= (SUMMARY);
509*fcf3ce44SJohn Forte 			else
510*fcf3ce44SJohn Forte 				dflags |= (SUMMARY | FLAGS);
511*fcf3ce44SJohn Forte 
512*fcf3ce44SJohn Forte 		if (user_rflags)
513*fcf3ce44SJohn Forte 			rflags = user_rflags;
514*fcf3ce44SJohn Forte 		else
515*fcf3ce44SJohn Forte 			rflags |= user_rflags;
516*fcf3ce44SJohn Forte 	}
517*fcf3ce44SJohn Forte 
518*fcf3ce44SJohn Forte 	error = do_stats();
519*fcf3ce44SJohn Forte 
520*fcf3ce44SJohn Forte 	if (error == EAGAIN) {
521*fcf3ce44SJohn Forte 		fail(DSSTAT_NOSTAT, gettext("No statistics available for the "
522*fcf3ce44SJohn Forte 		    "specified mode(s).\n"));
523*fcf3ce44SJohn Forte 	}
524*fcf3ce44SJohn Forte 
525*fcf3ce44SJohn Forte 	if (error == EINVAL) {
526*fcf3ce44SJohn Forte 		fail(DSSTAT_EINVAL,
527*fcf3ce44SJohn Forte 		    gettext("Invalid kstat format detected.\n"));
528*fcf3ce44SJohn Forte 	}
529*fcf3ce44SJohn Forte 
530*fcf3ce44SJohn Forte 	if (error == ENOMEM) {
531*fcf3ce44SJohn Forte 		fail(DSSTAT_ENOMEM,
532*fcf3ce44SJohn Forte 		    gettext("Unable to open kstat device for reading.\n"));
533*fcf3ce44SJohn Forte 	}
534*fcf3ce44SJohn Forte 
535*fcf3ce44SJohn Forte 	if (error == -1) {
536*fcf3ce44SJohn Forte 		if (execv("/usr/sbin/dsstat", argv) != 0) {
537*fcf3ce44SJohn Forte 			fail(DSSTAT_EMAP, gettext("Kstat is invalid.\n"));
538*fcf3ce44SJohn Forte 		}
539*fcf3ce44SJohn Forte 	}
540*fcf3ce44SJohn Forte 
541*fcf3ce44SJohn Forte 	if (error) {
542*fcf3ce44SJohn Forte 		fail(DSSTAT_EUNKNWN, gettext("An unknown error occured.\n"));
543*fcf3ce44SJohn Forte 	}
544*fcf3ce44SJohn Forte 
545*fcf3ce44SJohn Forte 	return (0);
546*fcf3ce44SJohn Forte }
547