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