1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <errno.h>
31
32 #include <sys/mutex.h>
33
34 #include <kstat.h>
35
36 #include <sys/unistat/spcs_s.h>
37 #include <sys/nsctl/dsw.h>
38 #include "../../../uts/common/avs/ns/dsw/dsw_dev.h"
39 #include <sys/nsctl/dsw_dev.h>
40
41 #include "sdbc_stats.h"
42 #include "ii_stats.h"
43
44 #include "dsstat.h"
45 #include "common.h"
46 #include "report.h"
47
48 static iistat_t *ii_top = NULL;
49
50 void ii_add_stat(iistat_t *);
51 iistat_t *ii_del_stat(iistat_t *);
52
53 int ii_value_check(iistat_t *iistat);
54 int ii_validate(kstat_t *ksp);
55 int ii_vol_selected(kstat_t *);
56
57 /*
58 * ii_discover() - looks for new statistics to be monitored.
59 * Verifies that any statistics found are now already being
60 * monitored.
61 *
62 */
63 int
ii_discover(kstat_ctl_t * kc)64 ii_discover(kstat_ctl_t *kc)
65 {
66 static int validated = 0;
67
68 kstat_t *ksp;
69
70 /* Loop on all kstats */
71 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
72 char *kname;
73 iistat_t *cur;
74 iistat_t *iistat = NULL;
75 kstat_t *mst_ksp;
76 kstat_t *shd_ksp;
77 kstat_t *bmp_ksp;
78 kstat_t *ovr_ksp;
79
80 /* Search for II set */
81 if (strcmp(ksp->ks_class, II_KSTAT_CLASS) != 0)
82 continue;
83
84 if (kstat_read(kc, ksp, NULL) == -1)
85 continue;
86
87 /*
88 * Validate kstat structure
89 */
90 if (! validated) {
91 if (ii_validate(ksp))
92 return (EINVAL);
93
94 validated++;
95 }
96
97 /*
98 * Duplicate check
99 */
100 for (cur = ii_top; cur != NULL; cur = cur->next) {
101 char *cur_vname, *tst_vname;
102 uint32_t cur_inst, tst_inst;
103
104 cur_vname = cur->pre_set->ks_name;
105 cur_inst = cur->pre_set->ks_instance;
106
107 tst_vname = ksp->ks_name;
108 tst_inst = ksp->ks_instance;
109
110 if (strcmp(cur_vname, tst_vname) == 0 &&
111 cur_inst == tst_inst)
112 goto next;
113 }
114
115 /*
116 * Initialize new record
117 */
118 iistat = (iistat_t *)calloc(1, sizeof (iistat_t));
119
120 /*
121 * Set kstat
122 */
123 iistat->pre_set = kstat_retrieve(kc, ksp);
124
125 if (iistat->pre_set == NULL)
126 goto next;
127
128 iistat->collected |= GOT_SETSTAT;
129
130 /*
131 * Master kstat
132 */
133 kname = kstat_value(iistat->pre_set, DSW_SKSTAT_MSTIO);
134
135 mst_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
136 iistat->pre_mst = kstat_retrieve(kc, mst_ksp);
137
138 if (iistat->pre_mst == NULL)
139 goto next;
140
141 iistat->collected |= GOT_MSTSTAT;
142
143 /*
144 * Shadow kstat
145 */
146 kname = kstat_value(iistat->pre_set, DSW_SKSTAT_SHDIO);
147
148 shd_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
149 iistat->pre_shd = kstat_retrieve(kc, shd_ksp);
150
151 if (iistat->pre_shd == NULL)
152 goto next;
153
154 iistat->collected |= GOT_SHDSTAT;
155
156 /*
157 * Bitmap kstat
158 */
159 kname = kstat_value(iistat->pre_set, DSW_SKSTAT_BMPIO);
160
161 bmp_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
162 iistat->pre_bmp = kstat_retrieve(kc, bmp_ksp);
163
164 if (iistat->pre_bmp == NULL)
165 goto next;
166
167 iistat->collected |= GOT_BMPSTAT;
168
169 /*
170 * Overflow kstat
171 */
172 kname = kstat_value(iistat->pre_set, DSW_SKSTAT_OVRIO);
173
174 ovr_ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
175 iistat->pre_ovr = kstat_retrieve(kc, ovr_ksp);
176
177 if (iistat->pre_ovr == NULL)
178 goto next;
179
180 iistat->collected |= GOT_OVRSTAT;
181
182 next:
183 /*
184 * Check if we got a complete set of stats
185 */
186 if (iistat == NULL)
187 continue;
188
189 if (IIMG_COMPLETE(iistat->collected)) {
190 (void) ii_del_stat(iistat);
191 continue;
192 }
193
194 /*
195 * Add to linked list
196 */
197 ii_add_stat(iistat);
198 }
199
200 if (ii_top == NULL)
201 return (EAGAIN);
202
203 return (0);
204 }
205
206 /*
207 * ii_update() - updates all of the statistics currently being monitored.
208 *
209 */
210 int
ii_update(kstat_ctl_t * kc)211 ii_update(kstat_ctl_t *kc)
212 {
213 iistat_t *cur;
214
215 for (cur = ii_top; cur != NULL; cur = cur->next) {
216 char volname[KSTAT_STRLEN + 1];
217 char *kname;
218
219 kstat_t *ksp = NULL;
220
221 cur->collected = 0;
222
223 /*
224 * Age off old stats
225 */
226 if (cur->cur_set != NULL) {
227 kstat_free(cur->pre_set);
228 kstat_free(cur->pre_mst);
229 kstat_free(cur->pre_shd);
230 kstat_free(cur->pre_bmp);
231
232 cur->pre_set = cur->cur_set;
233 cur->pre_mst = cur->cur_mst;
234 cur->pre_shd = cur->cur_shd;
235 cur->pre_bmp = cur->cur_bmp;
236
237 if (cur->cur_ovr != NULL) {
238 kstat_free(cur->pre_ovr);
239 cur->pre_ovr = cur->cur_ovr;
240 }
241 }
242
243 /*
244 * Set kstat
245 */
246 (void) strncpy(volname, cur->pre_set->ks_name, KSTAT_STRLEN);
247 volname[KSTAT_STRLEN] = '\0';
248
249 ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, volname);
250
251 if ((cur->cur_set = kstat_retrieve(kc, ksp)) == NULL)
252 continue;
253
254 cur->collected |= GOT_SETSTAT;
255
256 /*
257 * Validate set
258 */
259 if (strcmp(cur->pre_set->ks_name, cur->cur_set->ks_name) != 0 ||
260 cur->pre_set->ks_instance != cur->cur_set->ks_instance)
261 continue;
262
263 /*
264 * Master kstat
265 */
266 kname = kstat_value(cur->cur_set, DSW_SKSTAT_MSTIO);
267
268 ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
269
270 if ((cur->cur_mst = kstat_retrieve(kc, ksp)) == NULL)
271 continue;
272
273 cur->collected |= GOT_MSTSTAT;
274
275 /*
276 * Shadow kstat
277 */
278 kname = kstat_value(cur->cur_set, DSW_SKSTAT_SHDIO);
279
280 ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
281
282 if ((cur->cur_shd = kstat_retrieve(kc, ksp)) == NULL)
283 continue;
284
285 cur->collected |= GOT_SHDSTAT;
286
287 /*
288 * Bitmap kstat
289 */
290 kname = kstat_value(cur->pre_set, DSW_SKSTAT_BMPIO);
291
292 ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
293
294 if ((cur->cur_bmp = kstat_retrieve(kc, ksp)) == NULL)
295 continue;
296
297 cur->collected |= GOT_BMPSTAT;
298
299 /*
300 * Overflow kstat
301 */
302 kname = kstat_value(cur->cur_set, DSW_SKSTAT_OVRIO);
303
304 ksp = kstat_lookup(kc, II_KSTAT_MODULE, -1, kname);
305
306 if (ksp == NULL) {
307 if (cur->pre_ovr != NULL) {
308 kstat_free(cur->pre_ovr);
309 cur->pre_ovr = NULL;
310 }
311 if (cur->cur_ovr != NULL) {
312 kstat_free(cur->cur_ovr);
313 cur->cur_ovr = NULL;
314 }
315 continue;
316 }
317
318 if (cur->pre_ovr == NULL) {
319 if ((cur->pre_ovr = kstat_retrieve(kc, ksp)) == NULL)
320 continue;
321 } else {
322 if ((cur->cur_ovr = kstat_retrieve(kc, ksp)) == NULL)
323 continue;
324 }
325
326 cur->collected |= GOT_OVRSTAT;
327 }
328
329 return (0);
330 }
331
332 /*
333 * ii_report() - outputs statistics for the statistics currently being
334 * monitored. Deletes statistics for volumes that have been disabled.
335 *
336 */
337 int
ii_report()338 ii_report()
339 {
340 uint32_t *flags;
341 int padsz = 0;
342 char pad[20] = {0};
343 iistat_t *cur, *pre = NULL;
344
345 if (ii_top == NULL) {
346 return (0);
347 }
348
349 /* Create padding string for secondary report lines */
350 if (dflags & FLAGS) {
351 padsz += STAT_HDR_SIZE;
352 padsz += STAT_HDR_SIZE;
353 }
354
355 if (dflags & PCTS)
356 padsz += PCT_HDR_SIZE;
357
358 if (padsz) {
359 char fmt[20];
360 (void) sprintf(fmt, "%%%ds", padsz);
361 (void) sprintf(pad, fmt, "");
362 }
363
364 for (cur = ii_top; cur; /* CSTYLED */) {
365 int first = 1;
366 char data[20] = {0};
367
368 /* Check to see if this is this a complete */
369 if (IIMG_COMPLETE(cur->collected)) {
370 char *c;
371 char vol[(NAMED_LEN * 4) + 1] = {0};
372 int offset;
373 iistat_t *next;
374
375 /* notify user of set being disabled */
376 c = kstat_value(cur->pre_set, DSW_SKSTAT_SETA);
377 (void) strncpy(vol, c, NAMED_LEN);
378 c = kstat_value(cur->pre_set, DSW_SKSTAT_SETB);
379 (void) strncat(vol, c, NAMED_LEN);
380 c = kstat_value(cur->pre_set, DSW_SKSTAT_SETC);
381 (void) strncat(vol, c, NAMED_LEN);
382 c = kstat_value(cur->pre_set, DSW_SKSTAT_SETD);
383 (void) strncat(vol, c, NAMED_LEN);
384
385 offset = strlen(vol) - NAMED_LEN;
386
387 if (offset < 0)
388 offset = 0;
389
390 (void) printf(DATA_C16, vol + offset);
391 (void) printf(" %s\n", II_DISABLED);
392
393 /* free memory and remove stat from list */
394 next = ii_del_stat(cur);
395
396 if (! pre)
397 cur = ii_top = next;
398 else
399 cur = pre->next = next;
400
401 continue;
402 }
403
404 /* Check to see if the user specified this volume */
405 if (! ii_vol_selected(cur->pre_set))
406 goto next;
407
408 /* Check to see if zflag applies */
409 if (zflag && ii_value_check(cur) == 0)
410 goto next;
411
412 /* Calculate flags */
413 flags = kstat_value(cur->cur_set, DSW_SKSTAT_FLAGS);
414
415 if (dflags & FLAGS) {
416
417 char c[STAT_HDR_SIZE];
418 char vtype[STAT_HDR_SIZE];
419 char vstat[STAT_HDR_SIZE];
420
421 if (*flags & DSW_GOLDEN)
422 (void) strcpy(c, II_INDEPENDENT);
423 else
424 (void) strcpy(c, II_DEPENDENT);
425
426 (void) sprintf(vtype, DATA_C2, c);
427 (void) strcat(data, vtype);
428
429 if (*flags & DSW_COPYINGP)
430 (void) strcpy(c, II_COPYING);
431 else
432 (void) strcpy(c, NO_INFO);
433
434
435 (void) sprintf(vstat, DATA_C2, c);
436 (void) strcat(data, vstat);
437 }
438
439 /* Calculate sync needed precentage */
440 if (dflags & PCTS) {
441 char snpct[10];
442 uint32_t *chkbits;
443 uint32_t *cpybits;
444 uint32_t *shdbits;
445 uint32_t *volsize;
446 float pct;
447
448 cpybits =
449 kstat_value(cur->cur_set, DSW_SKSTAT_COPYBITS);
450
451 shdbits =
452 kstat_value(cur->cur_set, DSW_SKSTAT_SHDBITS);
453
454 volsize =
455 kstat_value(cur->cur_set, DSW_SKSTAT_SIZE);
456
457 *volsize /= DSW_SIZE;
458
459 chkbits = *cpybits >= *shdbits ? cpybits : shdbits;
460
461 pct = ((float)*chkbits / *volsize) * 100.0;
462
463 (void) sprintf(snpct, DATA_F62, pct);
464
465 (void) strcat(data, snpct);
466 }
467
468 /* Master statistics */
469 if (rflags & IIMG_MST) {
470 char *c;
471 char vol[(NAMED_LEN * 4) + 1] = {0};
472 int offset;
473
474 c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTA);
475 (void) strncat(vol, c, NAMED_LEN);
476 c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTB);
477 (void) strncat(vol, c, NAMED_LEN);
478 c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTC);
479 (void) strncat(vol, c, NAMED_LEN);
480 c = kstat_value(cur->cur_set, DSW_SKSTAT_MSTD);
481 (void) strncat(vol, c, NAMED_LEN);
482
483 offset = strlen(vol) - NAMED_LEN;
484
485 if (offset < 0)
486 offset = 0;
487
488 header();
489 (void) printf(DATA_C16, vol + offset);
490 (void) printf("%s", data);
491 (void) printf(ROLE_INF_FMT, II_MASTER);
492
493 if (*flags & DSW_MSTOFFLINE) {
494 (void) printf(" <<offline>>");
495 linesout++;
496 } else {
497 io_report(cur->cur_mst, cur->pre_mst,
498 sdbc_getstat(vol + offset));
499 }
500
501 (void) printf("\n");
502
503 if (first) {
504 (void) strcpy(data, strlen(pad) > 0 ? pad : "");
505 first = 0;
506 }
507 }
508
509 /* Shadow statistics */
510 if (rflags & IIMG_SHD) {
511 char *c;
512 char vol[(NAMED_LEN * 4) + 1] = {0};
513 int offset;
514
515 c = kstat_value(cur->cur_set, DSW_SKSTAT_SETA);
516 (void) strncat(vol, c, NAMED_LEN);
517 c = kstat_value(cur->cur_set, DSW_SKSTAT_SETB);
518 (void) strncat(vol, c, NAMED_LEN);
519 c = kstat_value(cur->cur_set, DSW_SKSTAT_SETC);
520 (void) strncat(vol, c, NAMED_LEN);
521 c = kstat_value(cur->cur_set, DSW_SKSTAT_SETD);
522 (void) strncat(vol, c, NAMED_LEN);
523
524 offset = strlen(vol) - NAMED_LEN;
525
526 if (offset < 0)
527 offset = 0;
528
529 header();
530 (void) printf(DATA_C16, vol + offset);
531 (void) printf("%s", data);
532 (void) printf(ROLE_INF_FMT, II_SHADOW);
533
534 if (*flags & DSW_SHDOFFLINE) {
535 (void) printf(" <<offline>>");
536 linesout++;
537 } else {
538 io_report(cur->cur_shd, cur->pre_shd,
539 sdbc_getstat(vol + offset));
540 }
541
542 (void) printf("\n");
543
544 if (first) {
545 (void) strcpy(data, strlen(pad) > 0 ? pad : "");
546 first = 0;
547 }
548 }
549
550 /* Bitmap statistics */
551 if (rflags & IIMG_BMP) {
552 char *c;
553 char vol[(NAMED_LEN * 4) + 1] = {0};
554 int offset;
555
556 c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPA);
557 (void) strncat(vol, c, NAMED_LEN);
558 c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPB);
559 (void) strncat(vol, c, NAMED_LEN);
560 c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPC);
561 (void) strncat(vol, c, NAMED_LEN);
562 c = kstat_value(cur->cur_set, DSW_SKSTAT_BMPD);
563 (void) strncat(vol, c, NAMED_LEN);
564
565 offset = strlen(vol) - NAMED_LEN;
566
567 if (offset < 0)
568 offset = 0;
569
570 header();
571 (void) printf(DATA_C16, vol + offset);
572 (void) printf("%s", data);
573 (void) printf(ROLE_INF_FMT, II_BITMAP);
574
575 if (*flags & DSW_BMPOFFLINE) {
576 (void) printf(" <<offline>>");
577 linesout++;
578 } else {
579 io_report(cur->cur_bmp, cur->pre_bmp,
580 sdbc_getstat(vol + offset));
581 }
582 (void) printf("\n");
583
584 if (first) {
585 (void) strcpy(data, strlen(pad) > 0 ? pad : "");
586 first = 0;
587 }
588 }
589
590 /* Overflow statistics */
591 if (rflags & IIMG_OVR) {
592 char *c;
593 char msg[20] = {0};
594 char vol[(NAMED_LEN * 4) + 1] = {0};
595 int offset;
596
597 if (cur->cur_ovr == NULL && cur->pre_ovr != NULL)
598 (void) strcpy(msg, " <<attached>>");
599
600 if (! (cur->collected & GOT_OVRSTAT))
601 (void) strcpy(msg, " <<not attached>>");
602
603 c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRA);
604 (void) strncpy(vol, c, NAMED_LEN);
605 c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRB);
606 (void) strncat(vol, c, NAMED_LEN);
607 c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRC);
608 (void) strncat(vol, c, NAMED_LEN);
609 c = kstat_value(cur->cur_set, DSW_SKSTAT_OVRD);
610 (void) strncat(vol, c, NAMED_LEN);
611
612 offset = strlen(vol) - NAMED_LEN;
613
614 if (offset < 0)
615 offset = 0;
616
617 header();
618 (void) printf(DATA_C16, vol + offset);
619 (void) printf("%s", data);
620 (void) printf(ROLE_INF_FMT, II_OVERFLOW);
621
622 if (strlen(msg)) {
623 (void) printf("%s\n", msg);
624 linesout++;
625 goto next;
626 }
627
628 if (*flags & DSW_OVROFFLINE) {
629 (void) printf(" <<offline>>");
630 linesout++;
631 } else {
632 io_report(cur->cur_ovr, cur->pre_ovr,
633 sdbc_getstat(vol + offset));
634 }
635
636 (void) printf("\n");
637
638 if (first) {
639 (void) strcpy(data, strlen(pad) > 0 ? pad : "");
640 first = 0;
641 }
642 }
643
644
645 next:
646 pre = cur;
647 cur = cur->next;
648 }
649
650 return (0);
651 }
652
653 /*
654 * ii_add_stat() - adds a fully populated iistat_t structure
655 * to the linked list of currently monitored kstats. The structure
656 * will be added in alphabetical order, using the volume name of
657 * the shadow volume as the key.
658 *
659 */
660 void
ii_add_stat(iistat_t * iistat)661 ii_add_stat(iistat_t *iistat)
662 {
663
664 iistat_t *cur;
665
666 if (ii_top == NULL) {
667 ii_top = iistat;
668 return;
669 }
670
671 for (cur = ii_top; cur != NULL; cur = cur->next) {
672 if (strcmp(cur->pre_set->ks_name,
673 iistat->pre_set->ks_name) <= 0) {
674 /*
675 * If we get to the last item in the list, then just
676 * add this one to the end
677 */
678 if (cur->next == NULL) {
679 cur->next = iistat;
680 return;
681 }
682
683 if (strcmp(cur->next->pre_set->ks_name,
684 iistat->pre_set->ks_name) > 0) {
685 iistat->next = cur->next;
686 cur->next = iistat;
687 return;
688 }
689 } else {
690 if (cur == ii_top)
691 ii_top = iistat;
692
693 iistat->next = cur;
694
695 return;
696 }
697 }
698 }
699
700 /*
701 * ii_del_stat() - deallocate memory for the structure being
702 * passed in.
703 *
704 * parameters
705 * iistat_t *iistat - structure to be deallocated
706 *
707 * returns
708 * iistat_t * - pointer to the "next" structures in the
709 * linked list. May be NULL if we are removing the last
710 * structure in the linked list.
711 *
712 */
713 iistat_t *
ii_del_stat(iistat_t * iistat)714 ii_del_stat(iistat_t *iistat)
715 {
716
717 iistat_t *next = iistat->next;
718
719 kstat_free(iistat->pre_set);
720 kstat_free(iistat->pre_mst);
721 kstat_free(iistat->pre_shd);
722 kstat_free(iistat->pre_bmp);
723 kstat_free(iistat->pre_ovr);
724 kstat_free(iistat->cur_set);
725 kstat_free(iistat->cur_mst);
726 kstat_free(iistat->cur_shd);
727 kstat_free(iistat->cur_bmp);
728 kstat_free(iistat->cur_ovr);
729
730 free(iistat);
731
732 return (next);
733 }
734
735 int
ii_value_check(iistat_t * iistat)736 ii_value_check(iistat_t *iistat)
737 {
738 if (IIMG_COMPLETE(iistat->collected))
739 return (1);
740
741 if (io_value_check(iistat->pre_mst->ks_data,
742 iistat->cur_mst->ks_data)) {
743 return (1);
744 }
745
746 if (io_value_check(iistat->pre_shd->ks_data,
747 iistat->cur_shd->ks_data)) {
748 return (1);
749 }
750
751 if (io_value_check(iistat->pre_bmp->ks_data,
752 iistat->cur_bmp->ks_data)) {
753 return (1);
754 }
755
756 if (iistat->pre_ovr && iistat->cur_ovr) {
757 if (io_value_check(iistat->pre_ovr->ks_data,
758 iistat->cur_ovr->ks_data)) {
759 return (1);
760 }
761 }
762
763 return (0);
764 }
765
766 int
ii_validate(kstat_t * ksp)767 ii_validate(kstat_t *ksp)
768 {
769 if (! kstat_value(ksp, DSW_SKSTAT_MSTIO) ||
770 ! kstat_value(ksp, DSW_SKSTAT_SHDIO) ||
771 ! kstat_value(ksp, DSW_SKSTAT_BMPIO) ||
772 ! kstat_value(ksp, DSW_SKSTAT_OVRIO) ||
773 ! kstat_value(ksp, DSW_SKSTAT_FLAGS) ||
774 ! kstat_value(ksp, DSW_SKSTAT_MSTA) ||
775 ! kstat_value(ksp, DSW_SKSTAT_SETA) ||
776 ! kstat_value(ksp, DSW_SKSTAT_BMPA) ||
777 ! kstat_value(ksp, DSW_SKSTAT_OVRA) ||
778 ! kstat_value(ksp, DSW_SKSTAT_SHDBITS) ||
779 ! kstat_value(ksp, DSW_SKSTAT_COPYBITS) ||
780 ! kstat_value(ksp, DSW_SKSTAT_SIZE))
781 return (1);
782
783 return (0);
784 }
785
786 int
ii_vol_selected(kstat_t * ksp)787 ii_vol_selected(kstat_t *ksp)
788 {
789 vslist_t *vslist = vs_top;
790
791 for (vslist = vs_top; vslist != NULL; vslist = vslist->next) {
792 char *vn;
793 int off = 0;
794
795 vn = ksp->ks_name;
796
797 if ((off = strlen(vn) - NAMED_LEN) <= 0) {
798 off = 0;
799 }
800
801 if (strcmp(vslist->volname, &vn[off]) == 0) {
802 break;
803 }
804 }
805
806 if (vs_top != NULL && vslist == NULL) {
807 return (0);
808 } else {
809 return (1);
810 }
811 }
812