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