4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
37 #include "multi_stats.h"
46 short hflags
= HEADERS_EXL
;
49 vslist_t
*vs_top
= NULL
;
55 (void) fprintf(stderr
, msg
);
62 "\ndsstat [-m <mode>[,<mode>]] [-f | -F] [-z] [-s <sets>] "
63 "[-r <flags>] \\\n[-d <flags>] [<interval> [<count>]]\n\n"));
72 "-d <flags> Specifies the statistics to be displayed\n\n"));
74 " For 'cache' mode\n"));
76 " Valid <flags> are 'rwfsdc', default <flags> are 'sf'\n"));
78 " r=read, w=write, f=flags, s=summary,\n"));
80 " only available for cache mode, need to combine with '-m'\n"));
82 " d=destaged, c=write cancellations\n\n"));
84 " For 'ii' mode;\n"));
86 " Valid <flags> are 'rwtfps', default <flags> are 'sf'\n"));
88 " r=read, w=write, t=timing, f=flags, p=percentages,\n"));
92 " For 'sndr' mode;\n"));
94 " Valid <flags> are'rwtfpsq', default <flags> are 'spf'\n"));
96 " r=read, w=write, t=timing, f=flags, p=percentages,\n"));
100 " only available for sndr mode, need to combine with '-m'\n"));
104 "-f prints field headers once for each iteration\n\n"));
106 "-F prints field headers once, at the start of reporting\n\n"));
108 "-h prints detailed usage message\n\n"));
110 "-m <mode>[,<mode>] where mode is, 'cache', 'ii', or 'sndr'\n\n"));
112 " Multiple modes may be specified as a comma separated list,\n"));
114 " or multiple -m switches may be used.\n\n"));
116 "-r <flags> specifies components to be reported\n\n"));
118 " For 'cache' mode, this option is not used.\n\n"));
120 " For 'ii' mode;\n"));
122 " Valid <flags> are 'msbo', default <flags> are 'msbo'\n"));
124 " m=master, s=shadow, b=bitmap, o=overflow\n\n"));
126 " For 'sndr' mode;\n"));
128 " Valid <flags> are 'nb', default <flags> are 'nb'\n"));
130 " n=network, b=bitmap\n\n"));
132 "-s <sets> outputs specified sets\n"));
134 " Where <sets> is a comma delimited list of set names\n\n"));
136 "-z suppress reports with zero value (no activity)\n\n"));
138 "<interval> is the number of seconds between reports\n\n"));
140 "<count> is the number of reports to be generated\n\n"));
144 fail(int err
, char *msg
)
146 errout(gettext("\ndsstat: "));
151 errout(gettext("For detailed usage run \"dsstat -h\"\n"));
157 set_mode(char *user_modes
)
162 for (m
= strtok(user_modes
, ","); m
!= NULL
; m
= strtok(NULL
, ",")) {
163 if (local_mode
!= 0) {
167 if (strncasecmp("sndr", m
, strlen(m
)) == 0) {
172 if (strncasecmp("ii", m
, strlen(m
)) == 0) {
177 if (strncasecmp("cache", m
, strlen(m
)) == 0) {
182 fail(DSSTAT_EINVAL
, gettext("Invalid mode specified"));
189 set_dflags(char *flags
)
192 short user_dflags
= 0;
194 for (index
= 0; index
< strlen(flags
); index
++) {
195 switch (flags
[index
]) {
200 user_dflags
|= WRITE
;
203 user_dflags
|= TIMING
;
206 user_dflags
|= FLAGS
;
212 user_dflags
|= SUMMARY
;
215 user_dflags
|= DESTAGED
;
218 user_dflags
|= WRCANCEL
;
221 user_dflags
|= RATIO
;
224 user_dflags
|= ASYNC_QUEUE
;
228 gettext("Invalid display-flags set\n"));
232 return (user_dflags
);
236 set_rflags(char *flags
)
239 short user_rflags
= 0;
241 for (index
= 0; index
< strlen(flags
); index
++) {
242 switch (flags
[index
]) {
244 user_rflags
|= IIMG_MST
;
247 user_rflags
|= IIMG_SHD
;
250 user_rflags
|= IIMG_BMP
;
251 user_rflags
|= SNDR_BMP
;
254 user_rflags
|= IIMG_OVR
;
257 user_rflags
|= SNDR_NET
;
261 gettext("Invalid report-flags set\n"));
265 return (user_rflags
);
269 set_vol_list(char *list
)
276 for (volume
= strtok(list
, ","); volume
!= NULL
;
277 volume
= strtok(NULL
, ",")) {
282 /* get user-specified set information */
283 if ((vn
= strchr(volume
, ':')) == NULL
) {
291 /* check for duplicates */
294 for (vslist
= vs_top
; vslist
!= NULL
; vslist
= vslist
->next
) {
295 if (vslist
->volhost
&& vh
) {
296 if (strcmp(vslist
->volhost
, vh
) == 0 &&
297 strcmp(vslist
->volname
, vn
) == 0)
300 if (strcmp(vslist
->volname
, vn
) == 0)
310 /* initialize new vslist record */
311 newvol
= (vslist_t
*)calloc(1, sizeof (vslist_t
));
313 newvol
->volname
= (char *)calloc((strlen(vn
) + 1),
315 (void) strcpy(newvol
->volname
, vn
);
320 newvol
->volhost
= (char *)calloc((strlen(vh
) + 1),
322 (void) strcpy(newvol
->volhost
, vh
);
326 if (vs_top
== NULL
) {
327 vslist
= vs_top
= newvol
;
332 if (vslist
== NULL
) {
333 vslist
= pre
->next
= newvol
;
341 main(int argc
, char **argv
)
348 short user_dflags
= 0;
349 short user_rflags
= 0;
351 /* Parse command line */
352 while ((c
= getopt(argc
, argv
, "d:fFhm:r:s:z")) != EOF
) {
354 case 'd': /* what to display */
355 user_dflags
= set_dflags(optarg
);
358 hflags
= HEADERS_ATT
;
361 hflags
= HEADERS_BOR
;
363 case 'h': /* usage */
368 mode
|= set_mode(optarg
);
370 case 'r': /* what to report on */
371 user_rflags
= set_rflags(optarg
);
374 set_vol_list(optarg
);
382 "Invalid argument specified\n");
386 /* Parse additional arguments */
388 if ((interval
= atoi(argv
[optind
])) <= 0) {
390 gettext("Invalid interval specified.\n"));
398 if ((iterations
= atoi(argv
[optind
])) <= 0) {
400 gettext("Invalid count specified.\n"));
409 gettext("Too many parameters specified.\n"));
413 mode
|= MULTI
| IIMG
| SNDR
| SDBC
;
415 /* Select statistics to gather */
417 if (! (mode
& MULTI
)) {
418 if (user_rflags
& IIMG_BMP
)
419 user_rflags
^= IIMG_BMP
;
421 if ((user_dflags
| SNDR_DIS_MASK
) != SNDR_DIS_MASK
) {
422 fail(DSSTAT_EINVAL
, gettext("Invalid "
423 "display-flags for RemoteMirror\n"));
426 if ((user_rflags
| SNDR_REP_MASK
) != SNDR_REP_MASK
) {
428 gettext("Invalid report-flags for "
433 if ((mode
& MULTI
) && (user_dflags
& ASYNC_QUEUE
)) {
434 fail(DSSTAT_EINVAL
, gettext("Remote Mirror async. queue"
435 "statistics can not be displayed with mutiple "
440 dflags
= user_dflags
;
442 dflags
|= (SUMMARY
| PCTS
| FLAGS
| RATIO
);
445 rflags
= user_rflags
;
447 rflags
|= (SNDR_NET
| SNDR_BMP
);
451 if (! (mode
& MULTI
)) {
452 if (user_rflags
& SNDR_BMP
)
453 user_rflags
^= SNDR_BMP
;
455 if ((user_dflags
| IIMG_DIS_MASK
) != IIMG_DIS_MASK
) {
457 gettext("Invalid display-flags for "
458 "Point-in-Time Copy\n"));
461 if ((user_rflags
| IIMG_REP_MASK
) != IIMG_REP_MASK
) {
463 gettext("Invalid report-flags for "
464 "Point-in-Time Copy\n"));
469 dflags
= user_dflags
;
471 dflags
|= (SUMMARY
| PCTS
| FLAGS
| RATIO
);
474 rflags
= user_rflags
;
476 rflags
|= (IIMG_MST
| IIMG_SHD
| IIMG_BMP
| IIMG_OVR
);
480 if (! (mode
& MULTI
)) {
481 if ((user_dflags
| CACHE_DIS_MASK
) != CACHE_DIS_MASK
) {
482 fail(DSSTAT_EINVAL
, gettext("Invalid "
483 "display-flags for CACHE\n"));
486 if ((user_rflags
| CACHE_REP_MASK
) != CACHE_REP_MASK
) {
487 fail(DSSTAT_EINVAL
, gettext("Invalid "
488 "report-flags for CACHE\n"));
491 if ((user_dflags
& DESTAGED
) || (user_dflags
& WRCANCEL
)) {
492 if (user_dflags
& DESTAGED
)
493 fail(DSSTAT_EINVAL
, gettext("Cache, destaged "
494 "statistics can not be displayed with mutiple "
497 fail(DSSTAT_EINVAL
, gettext("Cache, write "
499 "statistics can not be displayed with mutiple "
505 dflags
= user_dflags
;
510 dflags
|= (SUMMARY
| FLAGS
);
513 rflags
= user_rflags
;
515 rflags
|= user_rflags
;
520 if (error
== EAGAIN
) {
521 fail(DSSTAT_NOSTAT
, gettext("No statistics available for the "
522 "specified mode(s).\n"));
525 if (error
== EINVAL
) {
527 gettext("Invalid kstat format detected.\n"));
530 if (error
== ENOMEM
) {
532 gettext("Unable to open kstat device for reading.\n"));
536 if (execv("/usr/sbin/dsstat", argv
) != 0) {
537 fail(DSSTAT_EMAP
, gettext("Kstat is invalid.\n"));
542 fail(DSSTAT_EUNKNWN
, gettext("An unknown error occured.\n"));