xref: /titanic_44/usr/src/cmd/avs/dsstat/sdbc_stats.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 
33fcf3ce44SJohn Forte #include <kstat.h>
34fcf3ce44SJohn Forte 
35fcf3ce44SJohn Forte #include <sys/nsctl/nsctl.h>
36fcf3ce44SJohn Forte #include <sys/nsctl/sd_bcache.h>
37fcf3ce44SJohn Forte 
38fcf3ce44SJohn Forte #include "sdbc_stats.h"
39fcf3ce44SJohn Forte 
40fcf3ce44SJohn Forte #include "dsstat.h"
41fcf3ce44SJohn Forte #include "common.h"
42fcf3ce44SJohn Forte #include "report.h"
43fcf3ce44SJohn Forte 
44fcf3ce44SJohn Forte static sdbcstat_t *sdbc_top;
45fcf3ce44SJohn Forte kstat_t *sdbc_global = NULL;
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte void sdbc_header();
48fcf3ce44SJohn Forte int sdbc_value_check(sdbcstat_t *);
49fcf3ce44SJohn Forte int sdbc_validate(kstat_t *);
50fcf3ce44SJohn Forte uint32_t sdbc_getdelta(sdbcstat_t *, char *);
51fcf3ce44SJohn Forte 
52fcf3ce44SJohn Forte void sdbc_addstat(sdbcstat_t *);
53fcf3ce44SJohn Forte sdbcstat_t *sdbc_delstat(sdbcstat_t *);
54fcf3ce44SJohn Forte void center(int, char *);
55fcf3ce44SJohn Forte 
56fcf3ce44SJohn Forte /*
57fcf3ce44SJohn Forte  * sdbc_discover() - looks for new statistics to be monitored.
58fcf3ce44SJohn Forte  * Verifies that any statistics found are now already being
59fcf3ce44SJohn Forte  * monitored.
60fcf3ce44SJohn Forte  *
61fcf3ce44SJohn Forte  */
62fcf3ce44SJohn Forte int
sdbc_discover(kstat_ctl_t * kc)63fcf3ce44SJohn Forte sdbc_discover(kstat_ctl_t *kc)
64fcf3ce44SJohn Forte {
65fcf3ce44SJohn Forte 	static int validated = 0;
66fcf3ce44SJohn Forte 
67fcf3ce44SJohn Forte 	kstat_t *ksp;
68fcf3ce44SJohn Forte 
69fcf3ce44SJohn Forte 	for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
70fcf3ce44SJohn Forte 		int kinst;
71fcf3ce44SJohn Forte 		char kname[KSTAT_STRLEN + 1];
72fcf3ce44SJohn Forte 		sdbcstat_t *cur;
73fcf3ce44SJohn Forte 		sdbcstat_t *sdbcstat = NULL;
74fcf3ce44SJohn Forte 		kstat_t *io_ksp;
75fcf3ce44SJohn Forte 
76fcf3ce44SJohn Forte 		if (strcmp(ksp->ks_module, SDBC_KSTAT_MODULE) != 0 ||
77fcf3ce44SJohn Forte 		    strncmp(ksp->ks_name, SDBC_KSTAT_CDSTATS, 2) != 0)
78fcf3ce44SJohn Forte 			continue;
79fcf3ce44SJohn Forte 
80fcf3ce44SJohn Forte 		if (kstat_read(kc, ksp, NULL) == -1)
81fcf3ce44SJohn Forte 			continue;
82fcf3ce44SJohn Forte 
83fcf3ce44SJohn Forte 		/*
84fcf3ce44SJohn Forte 		 * Validate kstat structure
85fcf3ce44SJohn Forte 		 */
86fcf3ce44SJohn Forte 		if (! validated) {
87fcf3ce44SJohn Forte 			if (sdbc_validate(ksp))
88fcf3ce44SJohn Forte 				return (EINVAL);
89fcf3ce44SJohn Forte 
90fcf3ce44SJohn Forte 			validated++;
91fcf3ce44SJohn Forte 		}
92fcf3ce44SJohn Forte 
93fcf3ce44SJohn Forte 		/*
94fcf3ce44SJohn Forte 		 * Duplicate check
95fcf3ce44SJohn Forte 		 */
96fcf3ce44SJohn Forte 		for (cur = sdbc_top; cur; cur = cur->next) {
97fcf3ce44SJohn Forte 			char *cur_vname, *tst_vname;
98fcf3ce44SJohn Forte 
99fcf3ce44SJohn Forte 			cur_vname = kstat_value(cur->pre_set,
100fcf3ce44SJohn Forte 			    SDBC_CDKSTAT_VOL_NAME);
101fcf3ce44SJohn Forte 
102fcf3ce44SJohn Forte 			tst_vname = kstat_value(ksp,
103fcf3ce44SJohn Forte 			    SDBC_CDKSTAT_VOL_NAME);
104fcf3ce44SJohn Forte 
105fcf3ce44SJohn Forte 			if (strncmp(cur_vname, tst_vname, NAMED_LEN) == 0)
106fcf3ce44SJohn Forte 				goto next;
107fcf3ce44SJohn Forte 		}
108fcf3ce44SJohn Forte 
109fcf3ce44SJohn Forte 		/*
110fcf3ce44SJohn Forte 		 * Initialize new record
111fcf3ce44SJohn Forte 		 */
112fcf3ce44SJohn Forte 		sdbcstat = (sdbcstat_t *)calloc(1, sizeof (sdbcstat_t));
113fcf3ce44SJohn Forte 
114fcf3ce44SJohn Forte 		kinst = ksp->ks_instance;
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte 		/*
117fcf3ce44SJohn Forte 		 * Set kstat
118fcf3ce44SJohn Forte 		 */
119fcf3ce44SJohn Forte 		sdbcstat->pre_set = kstat_retrieve(kc, ksp);
120fcf3ce44SJohn Forte 
121fcf3ce44SJohn Forte 		if (sdbcstat->pre_set == NULL)
122fcf3ce44SJohn Forte 			goto next;
123fcf3ce44SJohn Forte 
124fcf3ce44SJohn Forte 		sdbcstat->collected |= GOT_SET_KSTAT;
125fcf3ce44SJohn Forte 
126fcf3ce44SJohn Forte 		/*
127fcf3ce44SJohn Forte 		 * I/O kstat
128fcf3ce44SJohn Forte 		 */
129*570de38fSSurya Prakki 		(void) sprintf(kname, "%s%d",  SDBC_IOKSTAT_CDSTATS, kinst);
130fcf3ce44SJohn Forte 
131fcf3ce44SJohn Forte 		io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
132fcf3ce44SJohn Forte 		sdbcstat->pre_io = kstat_retrieve(kc, io_ksp);
133fcf3ce44SJohn Forte 
134fcf3ce44SJohn Forte 		if (sdbcstat->pre_io == NULL)
135fcf3ce44SJohn Forte 			goto next;
136fcf3ce44SJohn Forte 
137fcf3ce44SJohn Forte 		sdbcstat->collected |= GOT_IO_KSTAT;
138fcf3ce44SJohn Forte 
139fcf3ce44SJohn Forte next:
140fcf3ce44SJohn Forte 		/*
141fcf3ce44SJohn Forte 		 * Check if we got a complete set of stats
142fcf3ce44SJohn Forte 		 */
143fcf3ce44SJohn Forte 		if (sdbcstat == NULL)
144fcf3ce44SJohn Forte 			continue;
145fcf3ce44SJohn Forte 
146fcf3ce44SJohn Forte 		if (SDBC_COMPLETE(sdbcstat->collected)) {
147fcf3ce44SJohn Forte 			(void) sdbc_delstat(sdbcstat);
148fcf3ce44SJohn Forte 			continue;
149fcf3ce44SJohn Forte 		}
150fcf3ce44SJohn Forte 
151fcf3ce44SJohn Forte 		sdbc_addstat(sdbcstat);
152fcf3ce44SJohn Forte 	}
153fcf3ce44SJohn Forte 
154fcf3ce44SJohn Forte 	if (sdbc_top == NULL)
155fcf3ce44SJohn Forte 		return (EAGAIN);
156fcf3ce44SJohn Forte 
157fcf3ce44SJohn Forte 	return (0);
158fcf3ce44SJohn Forte }
159fcf3ce44SJohn Forte 
160fcf3ce44SJohn Forte /*
161fcf3ce44SJohn Forte  * sdbc_update() - updates all of the statistics currently being monitored.
162fcf3ce44SJohn Forte  *
163fcf3ce44SJohn Forte  */
164fcf3ce44SJohn Forte int
sdbc_update(kstat_ctl_t * kc)165fcf3ce44SJohn Forte sdbc_update(kstat_ctl_t *kc)
166fcf3ce44SJohn Forte {
167fcf3ce44SJohn Forte 	kstat_t *ksp;
168fcf3ce44SJohn Forte 	sdbcstat_t *cur;
169fcf3ce44SJohn Forte 
170fcf3ce44SJohn Forte 	/* Update global kstat information */
171fcf3ce44SJohn Forte 	ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, -1, SDBC_KSTAT_GSTATS);
172fcf3ce44SJohn Forte 
173fcf3ce44SJohn Forte 	if (ksp == NULL)
174fcf3ce44SJohn Forte 		return (EAGAIN);
175fcf3ce44SJohn Forte 
176fcf3ce44SJohn Forte 	if (sdbc_global)
177fcf3ce44SJohn Forte 		kstat_free(sdbc_global);
178fcf3ce44SJohn Forte 
179fcf3ce44SJohn Forte 	sdbc_global = kstat_retrieve(kc, ksp);
180fcf3ce44SJohn Forte 
181fcf3ce44SJohn Forte 	for (cur = sdbc_top; cur != NULL; cur = cur->next) {
182fcf3ce44SJohn Forte 		int kinst;
183fcf3ce44SJohn Forte 		char *kname, *cname, *pname;
184fcf3ce44SJohn Forte 
185fcf3ce44SJohn Forte 		kstat_t *set_ksp, *io_ksp;
186fcf3ce44SJohn Forte 
187fcf3ce44SJohn Forte 		cur->collected = 0;
188fcf3ce44SJohn Forte 
189fcf3ce44SJohn Forte 		/*
190fcf3ce44SJohn Forte 		 * Age off old stats
191fcf3ce44SJohn Forte 		 */
192fcf3ce44SJohn Forte 		if (cur->cur_set != NULL) {
193fcf3ce44SJohn Forte 			kstat_free(cur->pre_set);
194fcf3ce44SJohn Forte 			kstat_free(cur->pre_io);
195fcf3ce44SJohn Forte 
196fcf3ce44SJohn Forte 			cur->pre_set = cur->cur_set;
197fcf3ce44SJohn Forte 			cur->pre_io = cur->cur_io;
198fcf3ce44SJohn Forte 		}
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 		/*
201fcf3ce44SJohn Forte 		 * Update set kstat
202fcf3ce44SJohn Forte 		 */
203fcf3ce44SJohn Forte 		kinst = cur->pre_set->ks_instance;
204fcf3ce44SJohn Forte 		kname = cur->pre_set->ks_name;
205fcf3ce44SJohn Forte 
206fcf3ce44SJohn Forte 		set_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
207fcf3ce44SJohn Forte 
208fcf3ce44SJohn Forte 		if ((cur->cur_set = kstat_retrieve(kc, set_ksp)) == NULL)
209fcf3ce44SJohn Forte 			continue;
210fcf3ce44SJohn Forte 
211fcf3ce44SJohn Forte 		cur->collected |= GOT_SET_KSTAT;
212fcf3ce44SJohn Forte 
213fcf3ce44SJohn Forte 		/*
214fcf3ce44SJohn Forte 		 * Validate set
215fcf3ce44SJohn Forte 		 */
216fcf3ce44SJohn Forte 		pname = kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME);
217fcf3ce44SJohn Forte 		cname = kstat_value(cur->cur_set, SDBC_CDKSTAT_VOL_NAME);
218fcf3ce44SJohn Forte 
219fcf3ce44SJohn Forte 		if (strncmp(pname, cname, NAMED_LEN) != 0)
220fcf3ce44SJohn Forte 			continue;
221fcf3ce44SJohn Forte 
222fcf3ce44SJohn Forte 		/*
223fcf3ce44SJohn Forte 		 * Update I/O kstat
224fcf3ce44SJohn Forte 		 */
225fcf3ce44SJohn Forte 		kinst = cur->pre_io->ks_instance;
226fcf3ce44SJohn Forte 		kname = cur->pre_io->ks_name;
227fcf3ce44SJohn Forte 
228fcf3ce44SJohn Forte 		io_ksp = kstat_lookup(kc, SDBC_KSTAT_MODULE, kinst, kname);
229fcf3ce44SJohn Forte 
230fcf3ce44SJohn Forte 		if ((cur->cur_io = kstat_retrieve(kc, io_ksp)) == NULL)
231fcf3ce44SJohn Forte 			continue;
232fcf3ce44SJohn Forte 
233fcf3ce44SJohn Forte 		cur->collected |= GOT_IO_KSTAT;
234fcf3ce44SJohn Forte 	}
235fcf3ce44SJohn Forte 
236fcf3ce44SJohn Forte 	return (0);
237fcf3ce44SJohn Forte }
238fcf3ce44SJohn Forte 
239fcf3ce44SJohn Forte /*
240fcf3ce44SJohn Forte  * sdbc_report() - outputs statistics for the statistics currently being
241fcf3ce44SJohn Forte  * monitored.  Deletes statistics for volumes that have been disabled.
242fcf3ce44SJohn Forte  *
243fcf3ce44SJohn Forte  */
244fcf3ce44SJohn Forte int
sdbc_report()245fcf3ce44SJohn Forte sdbc_report()
246fcf3ce44SJohn Forte {
247fcf3ce44SJohn Forte 	vslist_t *vslist = vs_top;
248fcf3ce44SJohn Forte 	sdbcstat_t *cur, *pre = NULL;
249fcf3ce44SJohn Forte 
250fcf3ce44SJohn Forte 	if (sdbc_top == NULL)
251fcf3ce44SJohn Forte 		return (0);
252fcf3ce44SJohn Forte 
253fcf3ce44SJohn Forte 	for (cur = sdbc_top; cur != NULL; ) { /* CSTYLED */
254fcf3ce44SJohn Forte 		static uint32_t linesout = 0;
255fcf3ce44SJohn Forte 		uint32_t *offline;
256fcf3ce44SJohn Forte 
257fcf3ce44SJohn Forte 		char volname[NAMED_LEN + 1];
258fcf3ce44SJohn Forte 		char rmode[STAT_HDR_SIZE];
259fcf3ce44SJohn Forte 		char wmode[STAT_HDR_SIZE];
260fcf3ce44SJohn Forte 
261fcf3ce44SJohn Forte 		/* Parse volume name */
262*570de38fSSurya Prakki 		(void) strncpy(volname, kstat_value(cur->pre_set,
263fcf3ce44SJohn Forte 		    SDBC_CDKSTAT_VOL_NAME), NAMED_LEN);
264fcf3ce44SJohn Forte 		volname[NAMED_LEN] = '\0';
265fcf3ce44SJohn Forte 
266fcf3ce44SJohn Forte 		/* Check to see if the user specified this volume */
267fcf3ce44SJohn Forte 		for (vslist = vs_top; vslist != NULL; vslist = vslist->next)
268fcf3ce44SJohn Forte 			if (strcmp(volname, vslist->volname) == 0)
269fcf3ce44SJohn Forte 				break;
270fcf3ce44SJohn Forte 
271fcf3ce44SJohn Forte 		if (vs_top != NULL && vslist == NULL)
272fcf3ce44SJohn Forte 			goto next;
273fcf3ce44SJohn Forte 
274fcf3ce44SJohn Forte 		/* Check if volume is offline and zflag applies */
275fcf3ce44SJohn Forte 		if (zflag && sdbc_value_check(cur) == 0)
276fcf3ce44SJohn Forte 			goto next;
277fcf3ce44SJohn Forte 
278fcf3ce44SJohn Forte 		/* Output volume name */
279fcf3ce44SJohn Forte 		sdbc_header();
280fcf3ce44SJohn Forte 
281fcf3ce44SJohn Forte 		(void) printf(DATA_C16, volname);
282fcf3ce44SJohn Forte 
283fcf3ce44SJohn Forte 		if (SDBC_COMPLETE(cur->collected)) {
284fcf3ce44SJohn Forte 			sdbcstat_t *next = sdbc_delstat(cur);
285fcf3ce44SJohn Forte 
286fcf3ce44SJohn Forte 			if (! pre)
287fcf3ce44SJohn Forte 				cur = sdbc_top = next;
288fcf3ce44SJohn Forte 			else
289fcf3ce44SJohn Forte 				cur = pre->next = next;
290fcf3ce44SJohn Forte 
291fcf3ce44SJohn Forte 			(void) printf(" <<volume disabled>>\n");
292fcf3ce44SJohn Forte 			continue;
293fcf3ce44SJohn Forte 		}
294fcf3ce44SJohn Forte 
295fcf3ce44SJohn Forte 		offline = kstat_value(cur->cur_set, SDBC_CDKSTAT_FAILED);
296fcf3ce44SJohn Forte 		if (*offline) {
297fcf3ce44SJohn Forte 			(void) printf(" <<volume offline>>\n");
298fcf3ce44SJohn Forte 			linesout++;
299fcf3ce44SJohn Forte 			goto next;
300fcf3ce44SJohn Forte 		}
301fcf3ce44SJohn Forte 
302fcf3ce44SJohn Forte 		/* Type/status flags */
303fcf3ce44SJohn Forte 		if (dflags & FLAGS) {
304fcf3ce44SJohn Forte 
305fcf3ce44SJohn Forte 			uint32_t *dhint, *nhint;
306fcf3ce44SJohn Forte 			uint32_t hints;
307fcf3ce44SJohn Forte 
308fcf3ce44SJohn Forte 			dhint = kstat_value(cur->cur_set, SDBC_CDKSTAT_CDHINTS);
309fcf3ce44SJohn Forte 			nhint = kstat_value(sdbc_global, SDBC_GKSTAT_NODEHINTS);
310fcf3ce44SJohn Forte 
311fcf3ce44SJohn Forte 			if (! nhint)
312fcf3ce44SJohn Forte 				return (EINVAL);
313fcf3ce44SJohn Forte 
314fcf3ce44SJohn Forte 			hints = *nhint;
315fcf3ce44SJohn Forte 			hints &= (NSC_FORCED_WRTHRU | NSC_NO_FORCED_WRTHRU |
316fcf3ce44SJohn Forte 			    NSC_NOCACHE);
317fcf3ce44SJohn Forte 			hints |= *dhint;
318fcf3ce44SJohn Forte 
319fcf3ce44SJohn Forte 			if (hints & NSC_NOCACHE)
320fcf3ce44SJohn Forte 				(void) strcpy(rmode, "D");
321fcf3ce44SJohn Forte 			else
322fcf3ce44SJohn Forte 				(void) strcpy(rmode, "C");
323fcf3ce44SJohn Forte 
324fcf3ce44SJohn Forte 			if ((hints & NSC_FORCED_WRTHRU) || (hints & NSC_WRTHRU))
325fcf3ce44SJohn Forte 				(void) strcpy(wmode, "D");
326fcf3ce44SJohn Forte 			else
327fcf3ce44SJohn Forte 				(void) strcpy(wmode, "C");
328fcf3ce44SJohn Forte 
329fcf3ce44SJohn Forte 			(void) printf(DATA_C2, rmode);
330fcf3ce44SJohn Forte 			(void) printf(DATA_C2, wmode);
331fcf3ce44SJohn Forte 		}
332fcf3ce44SJohn Forte 
333fcf3ce44SJohn Forte 		/* Output set information */
334fcf3ce44SJohn Forte 		cd_report(cur);
335fcf3ce44SJohn Forte 
336fcf3ce44SJohn Forte next:
337fcf3ce44SJohn Forte 		pre = cur;
338fcf3ce44SJohn Forte 		cur = cur->next;
339fcf3ce44SJohn Forte 	}
340fcf3ce44SJohn Forte 
341fcf3ce44SJohn Forte 	return (0);
342fcf3ce44SJohn Forte }
343fcf3ce44SJohn Forte 
344fcf3ce44SJohn Forte /*
345fcf3ce44SJohn Forte  * sdbc_header() - outputs an appropriate header by referencing the
346fcf3ce44SJohn Forte  * global variables dflsgs
347fcf3ce44SJohn Forte  *
348fcf3ce44SJohn Forte  */
349fcf3ce44SJohn Forte void
sdbc_header()350fcf3ce44SJohn Forte sdbc_header()
351fcf3ce44SJohn Forte {
352fcf3ce44SJohn Forte 	int rcount = 0;
353fcf3ce44SJohn Forte 
354fcf3ce44SJohn Forte 	if (hflags == HEADERS_EXL)
355fcf3ce44SJohn Forte 		if ((linesout % DISPLAY_LINES) != 0)
356fcf3ce44SJohn Forte 			return;
357fcf3ce44SJohn Forte 
358fcf3ce44SJohn Forte 	if (hflags == HEADERS_BOR)
359fcf3ce44SJohn Forte 		if (linesout != 0)
360fcf3ce44SJohn Forte 			return;
361fcf3ce44SJohn Forte 
362fcf3ce44SJohn Forte 	if (hflags & HEADERS_ATT)
363fcf3ce44SJohn Forte 		if (hflags & HEADERS_OUT)
364fcf3ce44SJohn Forte 			return;
365fcf3ce44SJohn Forte 		else
366fcf3ce44SJohn Forte 			hflags |= HEADERS_OUT;
367fcf3ce44SJohn Forte 
368fcf3ce44SJohn Forte 	if (linesout)
369*570de38fSSurya Prakki 		(void) printf("\n");
370fcf3ce44SJohn Forte 
371fcf3ce44SJohn Forte 	/* first line header */
372fcf3ce44SJohn Forte 	if (! (dflags & SUMMARY) && dflags != FLAGS) {
373fcf3ce44SJohn Forte 
374fcf3ce44SJohn Forte 		(void) printf(VOL_HDR_FMT, " ");
375fcf3ce44SJohn Forte 
376fcf3ce44SJohn Forte 		if (dflags & FLAGS) {
377fcf3ce44SJohn Forte 			(void) printf(STAT_HDR_FMT, " ");
378fcf3ce44SJohn Forte 			(void) printf(STAT_HDR_FMT, " ");
379fcf3ce44SJohn Forte 		}
380fcf3ce44SJohn Forte 
381fcf3ce44SJohn Forte 		if (dflags & READ) {
382fcf3ce44SJohn Forte 			int size;
383fcf3ce44SJohn Forte 
384fcf3ce44SJohn Forte 			size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE;
385fcf3ce44SJohn Forte 			center(size, "- read -");
386fcf3ce44SJohn Forte 			rcount++;
387fcf3ce44SJohn Forte 		}
388fcf3ce44SJohn Forte 
389fcf3ce44SJohn Forte 		if (dflags & WRITE) {
390fcf3ce44SJohn Forte 			int size;
391fcf3ce44SJohn Forte 
392fcf3ce44SJohn Forte 			size = KPS_HDR_SIZE * 2 + HIT_HDR_SIZE;
393fcf3ce44SJohn Forte 			center(size, "- write -");
394fcf3ce44SJohn Forte 			rcount++;
395fcf3ce44SJohn Forte 		}
396fcf3ce44SJohn Forte 
397fcf3ce44SJohn Forte 		if (dflags != FLAGS)
398fcf3ce44SJohn Forte 			(void) printf("\n");
399fcf3ce44SJohn Forte 	}
400fcf3ce44SJohn Forte 
401fcf3ce44SJohn Forte 	/* second line header */
402fcf3ce44SJohn Forte 	(void) printf(VOL_HDR_FMT, "volume");
403fcf3ce44SJohn Forte 
404fcf3ce44SJohn Forte 	if (dflags & FLAGS) {
405fcf3ce44SJohn Forte 		(void) printf(STAT_HDR_FMT, "rd");
406fcf3ce44SJohn Forte 		(void) printf(STAT_HDR_FMT, "wr");
407fcf3ce44SJohn Forte 	}
408fcf3ce44SJohn Forte 
409fcf3ce44SJohn Forte 	if (dflags & SUMMARY) {
410fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "ckps");
411fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "dkps");
412fcf3ce44SJohn Forte 		(void) printf(HIT_HDR_FMT, HIT_HDR_TXT);
413fcf3ce44SJohn Forte 
414fcf3ce44SJohn Forte 		goto out;
415fcf3ce44SJohn Forte 	}
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 	if (dflags & READ) {
418fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "ckps");
419fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "dkps");
420fcf3ce44SJohn Forte 		(void) printf(HIT_HDR_FMT, RHIT_HDR_TXT);
421fcf3ce44SJohn Forte 	}
422fcf3ce44SJohn Forte 
423fcf3ce44SJohn Forte 	if (dflags & WRITE) {
424fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "ckps");
425fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "dkps");
426fcf3ce44SJohn Forte 		(void) printf(HIT_HDR_FMT, WHIT_HDR_TXT);
427fcf3ce44SJohn Forte 	}
428fcf3ce44SJohn Forte 
429fcf3ce44SJohn Forte 	if (dflags & DESTAGED)
430fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "dstg");
431fcf3ce44SJohn Forte 
432fcf3ce44SJohn Forte 	if (dflags & WRCANCEL)
433fcf3ce44SJohn Forte 		(void) printf(KPS_HDR_FMT, "cwrl");
434fcf3ce44SJohn Forte 
435fcf3ce44SJohn Forte out:
436fcf3ce44SJohn Forte 	(void) printf("\n");
437fcf3ce44SJohn Forte }
438fcf3ce44SJohn Forte 
439fcf3ce44SJohn Forte /*
440fcf3ce44SJohn Forte  * sdbc_getstat() - find cache stat by name matching
441fcf3ce44SJohn Forte  *
442fcf3ce44SJohn Forte  * paraemters
443fcf3ce44SJohn Forte  * 	char *vn - the volume name to match against
444fcf3ce44SJohn Forte  * returns
445fcf3ce44SJohn Forte  * 	sdbcstat_t * - the matching strcture, NULL if not found
446fcf3ce44SJohn Forte  */
447fcf3ce44SJohn Forte sdbcstat_t *
sdbc_getstat(char * vn)448fcf3ce44SJohn Forte sdbc_getstat(char *vn)
449fcf3ce44SJohn Forte {
450fcf3ce44SJohn Forte 	sdbcstat_t *cur, *pre = NULL;
451fcf3ce44SJohn Forte 
452fcf3ce44SJohn Forte 	for (cur = sdbc_top; cur; ) { /* CSTYLED */
453fcf3ce44SJohn Forte 		char *volname =
454fcf3ce44SJohn Forte 		    kstat_value(cur->pre_set, SDBC_CDKSTAT_VOL_NAME);
455fcf3ce44SJohn Forte 
456fcf3ce44SJohn Forte 		if (SDBC_COMPLETE(cur->collected)) {
457fcf3ce44SJohn Forte 			sdbcstat_t *next = sdbc_delstat(cur);
458fcf3ce44SJohn Forte 
459fcf3ce44SJohn Forte 			if (! pre)
460fcf3ce44SJohn Forte 				cur = sdbc_top = next;
461fcf3ce44SJohn Forte 			else
462fcf3ce44SJohn Forte 				cur = pre->next = next;
463fcf3ce44SJohn Forte 
464fcf3ce44SJohn Forte 			continue;
465fcf3ce44SJohn Forte 		}
466fcf3ce44SJohn Forte 
467fcf3ce44SJohn Forte 		if (strncmp(volname, vn, NAMED_LEN) == 0)
468fcf3ce44SJohn Forte 			return (cur);
469fcf3ce44SJohn Forte 
470fcf3ce44SJohn Forte 		pre = cur;
471fcf3ce44SJohn Forte 		cur = cur->next;
472fcf3ce44SJohn Forte 	}
473fcf3ce44SJohn Forte 
474fcf3ce44SJohn Forte 	return (NULL);
475fcf3ce44SJohn Forte }
476fcf3ce44SJohn Forte 
477fcf3ce44SJohn Forte /*
478fcf3ce44SJohn Forte  * sdbc_addstat() - adds a fully populated sdbcstat_t structure
479fcf3ce44SJohn Forte  * to the linked list of currently monitored kstats.  The structure
480fcf3ce44SJohn Forte  * will be added in alphabetical order, using the volume name as the
481fcf3ce44SJohn Forte  * key.
482fcf3ce44SJohn Forte  *
483fcf3ce44SJohn Forte  * parameters
484fcf3ce44SJohn Forte  * 	sdbcstat_t *sdbcstat - to be added to the list.
485fcf3ce44SJohn Forte  *
486fcf3ce44SJohn Forte  */
487fcf3ce44SJohn Forte void
sdbc_addstat(sdbcstat_t * sdbcstat)488fcf3ce44SJohn Forte sdbc_addstat(sdbcstat_t *sdbcstat)
489fcf3ce44SJohn Forte {
490fcf3ce44SJohn Forte 	sdbcstat_t *cur;
491fcf3ce44SJohn Forte 
492fcf3ce44SJohn Forte 	if (sdbc_top == NULL) {
493fcf3ce44SJohn Forte 		sdbc_top = sdbcstat;
494fcf3ce44SJohn Forte 		return;
495fcf3ce44SJohn Forte 	}
496fcf3ce44SJohn Forte 
497fcf3ce44SJohn Forte 	for (cur = sdbc_top; cur != NULL; cur = cur->next) {
498fcf3ce44SJohn Forte 		char *cur_vname, *nxt_vname, *tst_vname;
499fcf3ce44SJohn Forte 
500fcf3ce44SJohn Forte 		cur_vname = kstat_value(cur->pre_set,
501fcf3ce44SJohn Forte 		    SDBC_CDKSTAT_VOL_NAME);
502fcf3ce44SJohn Forte 		tst_vname = kstat_value(sdbcstat->pre_set,
503fcf3ce44SJohn Forte 		    SDBC_CDKSTAT_VOL_NAME);
504fcf3ce44SJohn Forte 
505fcf3ce44SJohn Forte 		if (strncmp(cur_vname, tst_vname, NAMED_LEN) > 0) {
506fcf3ce44SJohn Forte 			if (cur == sdbc_top)
507fcf3ce44SJohn Forte 				sdbc_top = sdbcstat;
508fcf3ce44SJohn Forte 
509fcf3ce44SJohn Forte 			sdbcstat->next = cur;
510fcf3ce44SJohn Forte 
511fcf3ce44SJohn Forte 			return;
512fcf3ce44SJohn Forte 		}
513fcf3ce44SJohn Forte 
514fcf3ce44SJohn Forte 		/*
515fcf3ce44SJohn Forte 		 * If we get to the last item in the list, then just
516fcf3ce44SJohn Forte 		 * add this one to the end
517fcf3ce44SJohn Forte 		 */
518fcf3ce44SJohn Forte 		if (cur->next == NULL) {
519fcf3ce44SJohn Forte 			cur->next = sdbcstat;
520fcf3ce44SJohn Forte 			return;
521fcf3ce44SJohn Forte 		}
522fcf3ce44SJohn Forte 
523fcf3ce44SJohn Forte 		nxt_vname = kstat_value(cur->next->pre_set,
524fcf3ce44SJohn Forte 		    SDBC_CDKSTAT_VOL_NAME);
525fcf3ce44SJohn Forte 
526fcf3ce44SJohn Forte 		if (strncmp(nxt_vname, tst_vname, NAMED_LEN) > 0) {
527fcf3ce44SJohn Forte 			sdbcstat->next = cur->next;
528fcf3ce44SJohn Forte 			cur->next = sdbcstat;
529fcf3ce44SJohn Forte 			return;
530fcf3ce44SJohn Forte 		}
531fcf3ce44SJohn Forte 	}
532fcf3ce44SJohn Forte }
533fcf3ce44SJohn Forte 
534fcf3ce44SJohn Forte /*
535fcf3ce44SJohn Forte  * sdbc_delstat() - deallocate memory for the structure being
536fcf3ce44SJohn Forte  * passed in.
537fcf3ce44SJohn Forte  *
538fcf3ce44SJohn Forte  * parameters
539fcf3ce44SJohn Forte  * 	sdbcstat_t *sdbcstat - structure to be deallocated
540fcf3ce44SJohn Forte  *
541fcf3ce44SJohn Forte  * returns
542fcf3ce44SJohn Forte  * 	sdbcstat_t * - pointer to the "next" structures in the
543fcf3ce44SJohn Forte  * 	linked list. May be NULL if we are removing the last
544fcf3ce44SJohn Forte  * 	structure in the linked list.
545fcf3ce44SJohn Forte  */
546fcf3ce44SJohn Forte sdbcstat_t *
sdbc_delstat(sdbcstat_t * sdbcstat)547fcf3ce44SJohn Forte sdbc_delstat(sdbcstat_t *sdbcstat)
548fcf3ce44SJohn Forte {
549fcf3ce44SJohn Forte 
550fcf3ce44SJohn Forte 	sdbcstat_t *next = sdbcstat->next;
551fcf3ce44SJohn Forte 
552fcf3ce44SJohn Forte 	kstat_free(sdbcstat->pre_set);
553fcf3ce44SJohn Forte 	kstat_free(sdbcstat->pre_io);
554fcf3ce44SJohn Forte 	kstat_free(sdbcstat->cur_set);
555fcf3ce44SJohn Forte 	kstat_free(sdbcstat->cur_io);
556fcf3ce44SJohn Forte 
557fcf3ce44SJohn Forte 	free(sdbcstat);
558fcf3ce44SJohn Forte 	sdbcstat = NULL;
559fcf3ce44SJohn Forte 
560fcf3ce44SJohn Forte 	return (next);
561fcf3ce44SJohn Forte }
562fcf3ce44SJohn Forte 
563fcf3ce44SJohn Forte /*
564fcf3ce44SJohn Forte  * sdbc_value_check() - Checks for activity, supports -z switch
565fcf3ce44SJohn Forte  *
566fcf3ce44SJohn Forte  * parameters
567fcf3ce44SJohn Forte  * 	sdbcstat_t *sdbcstat - structure to be checked
568fcf3ce44SJohn Forte  *
569fcf3ce44SJohn Forte  * returns
570fcf3ce44SJohn Forte  * 	1 - activity
571fcf3ce44SJohn Forte  * 	0 - no activity
572fcf3ce44SJohn Forte  */
573fcf3ce44SJohn Forte int
sdbc_value_check(sdbcstat_t * sdbcstat)574fcf3ce44SJohn Forte sdbc_value_check(sdbcstat_t *sdbcstat)
575fcf3ce44SJohn Forte {
576fcf3ce44SJohn Forte 	if (SDBC_COMPLETE(sdbcstat->collected))
577fcf3ce44SJohn Forte 		return (1);
578fcf3ce44SJohn Forte 
579fcf3ce44SJohn Forte 	if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ) != 0)
580fcf3ce44SJohn Forte 		return (1);
581fcf3ce44SJohn Forte 
582fcf3ce44SJohn Forte 	if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ) != 0)
583fcf3ce44SJohn Forte 		return (1);
584fcf3ce44SJohn Forte 
585fcf3ce44SJohn Forte 	if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE) != 0)
586fcf3ce44SJohn Forte 		return (1);
587fcf3ce44SJohn Forte 
588fcf3ce44SJohn Forte 	if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE) != 0)
589fcf3ce44SJohn Forte 		return (1);
590fcf3ce44SJohn Forte 
591fcf3ce44SJohn Forte 	if (sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS) != 0)
592fcf3ce44SJohn Forte 		return (1);
593fcf3ce44SJohn Forte 
594fcf3ce44SJohn Forte 	if (io_value_check(sdbcstat->pre_io->ks_data,
595fcf3ce44SJohn Forte 	    sdbcstat->cur_io->ks_data) != 0)
596fcf3ce44SJohn Forte 		return (1);
597fcf3ce44SJohn Forte 
598fcf3ce44SJohn Forte 	return (0);
599fcf3ce44SJohn Forte }
600fcf3ce44SJohn Forte 
601fcf3ce44SJohn Forte /*
602fcf3ce44SJohn Forte  * sdbc_validate() - validates the structure of the kstats by attempting to
603fcf3ce44SJohn Forte  *                   lookup fields used by this module
604fcf3ce44SJohn Forte  *
605fcf3ce44SJohn Forte  * parameters
606fcf3ce44SJohn Forte  *	kstat_t *ksp - kstat to be examined
607fcf3ce44SJohn Forte  *
608fcf3ce44SJohn Forte  * returns
609fcf3ce44SJohn Forte  * 	1 - one or more fields missing
610fcf3ce44SJohn Forte  * 	0 - all fields present
611fcf3ce44SJohn Forte  */
612fcf3ce44SJohn Forte int
sdbc_validate(kstat_t * ksp)613fcf3ce44SJohn Forte sdbc_validate(kstat_t *ksp)
614fcf3ce44SJohn Forte {
615fcf3ce44SJohn Forte 	if (! kstat_value(ksp, SDBC_CDKSTAT_VOL_NAME) ||
616fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_FAILED) ||
617fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_CDHINTS) ||
618fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_READ) ||
619fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_DISK_READ) ||
620fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_CACHE_WRITE) ||
621fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_DISK_WRITE) ||
622fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_DESTAGED) ||
623fcf3ce44SJohn Forte 	    ! kstat_value(ksp, SDBC_CDKSTAT_WRCANCELNS))
624fcf3ce44SJohn Forte 		return (1);
625fcf3ce44SJohn Forte 
626fcf3ce44SJohn Forte 	return (0);
627fcf3ce44SJohn Forte }
628fcf3ce44SJohn Forte 
629fcf3ce44SJohn Forte /*
630fcf3ce44SJohn Forte  * sdbc_getvalues() - populates a values structure with data obtained from the
631fcf3ce44SJohn Forte  *                    kstat
632fcf3ce44SJohn Forte  *
633fcf3ce44SJohn Forte  * parameters
634fcf3ce44SJohn Forte  * 	sdbcstat_t *sdbcstat - pointer to the structure containing the kstats
635fcf3ce44SJohn Forte  * 	sdbcvals_t *vals - pointer to the structure that will receive the values
636fcf3ce44SJohn Forte  * 	int flags - flags that describe adjustments made to the values
637fcf3ce44SJohn Forte  *
638fcf3ce44SJohn Forte  * returns
639fcf3ce44SJohn Forte  * 	1 - failure
640fcf3ce44SJohn Forte  * 	0 - success
641fcf3ce44SJohn Forte  */
642fcf3ce44SJohn Forte int
sdbc_getvalues(sdbcstat_t * sdbcstat,sdbcvals_t * vals,int flags)643fcf3ce44SJohn Forte sdbc_getvalues(sdbcstat_t *sdbcstat, sdbcvals_t *vals, int flags)
644fcf3ce44SJohn Forte {
645fcf3ce44SJohn Forte 	int divisor = 0;
646fcf3ce44SJohn Forte 	int factors;
647fcf3ce44SJohn Forte 	uint64_t hr_etime;
648fcf3ce44SJohn Forte 	double etime;
649fcf3ce44SJohn Forte 
650fcf3ce44SJohn Forte 	kstat_io_t *cur;
651fcf3ce44SJohn Forte 	kstat_io_t *pre;
652fcf3ce44SJohn Forte 
653fcf3ce44SJohn Forte 	if (sdbcstat == NULL)
654fcf3ce44SJohn Forte 		return (1);
655fcf3ce44SJohn Forte 
656fcf3ce44SJohn Forte 	cur = sdbcstat->cur_io->ks_data;
657fcf3ce44SJohn Forte 	pre = sdbcstat->pre_io->ks_data;
658fcf3ce44SJohn Forte 
659fcf3ce44SJohn Forte 	hr_etime = hrtime_delta(pre->rlastupdate, cur->rlastupdate);
660fcf3ce44SJohn Forte 	etime = hr_etime / (double)NANOSEC;
661fcf3ce44SJohn Forte 
662fcf3ce44SJohn Forte 	/* read data */
663fcf3ce44SJohn Forte 	vals->cache_read =
664fcf3ce44SJohn Forte 	    FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_READ));
665fcf3ce44SJohn Forte 	vals->disk_read =
666fcf3ce44SJohn Forte 	    FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_READ));
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 
669fcf3ce44SJohn Forte 	vals->total_reads = vals->cache_read + vals->disk_read;
670fcf3ce44SJohn Forte 
671fcf3ce44SJohn Forte 	if (vals->cache_read == 0)
672fcf3ce44SJohn Forte 		vals->read_hit = 0.0;
673fcf3ce44SJohn Forte 	else
674fcf3ce44SJohn Forte 		vals->read_hit =
675fcf3ce44SJohn Forte 		    ((float)vals->cache_read / vals->total_reads) * 100.0;
676fcf3ce44SJohn Forte 
677fcf3ce44SJohn Forte 	/* write data */
678fcf3ce44SJohn Forte 	vals->cache_write =
679fcf3ce44SJohn Forte 	    FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_CACHE_WRITE));
680fcf3ce44SJohn Forte 	vals->disk_write =
681fcf3ce44SJohn Forte 	    FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DISK_WRITE));
682fcf3ce44SJohn Forte 
683fcf3ce44SJohn Forte 	vals->total_writes = vals->cache_write + vals->disk_write;
684fcf3ce44SJohn Forte 
685fcf3ce44SJohn Forte 	vals->destaged =
686fcf3ce44SJohn Forte 	    FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_DESTAGED));
687fcf3ce44SJohn Forte 
688fcf3ce44SJohn Forte 	if (vals->cache_write == 0)
689fcf3ce44SJohn Forte 		vals->write_hit = 0.0;
690fcf3ce44SJohn Forte 	else
691fcf3ce44SJohn Forte 		vals->write_hit = ((float)vals->cache_write /
692fcf3ce44SJohn Forte 		    (vals->total_writes - vals->destaged)) * 100.0;
693fcf3ce44SJohn Forte 
694fcf3ce44SJohn Forte 	/* miscellaneous */
695fcf3ce44SJohn Forte 	vals->write_cancellations =
696fcf3ce44SJohn Forte 	    FBA_SIZE(sdbc_getdelta(sdbcstat, SDBC_CDKSTAT_WRCANCELNS));
697fcf3ce44SJohn Forte 
698fcf3ce44SJohn Forte 	vals->total_cache = vals->cache_read + vals->cache_write;
699fcf3ce44SJohn Forte 	vals->total_disk = vals->disk_read + vals->disk_write;
700fcf3ce44SJohn Forte 
701fcf3ce44SJohn Forte 	/* total cache hit calculation */
702fcf3ce44SJohn Forte 	vals->cache_hit = 0;
703fcf3ce44SJohn Forte 	factors = 0;
704fcf3ce44SJohn Forte 
705fcf3ce44SJohn Forte 	if (vals->cache_read != 0) {
706fcf3ce44SJohn Forte 		vals->cache_hit += vals->read_hit;
707fcf3ce44SJohn Forte 		factors++;
708fcf3ce44SJohn Forte 	}
709fcf3ce44SJohn Forte 
710fcf3ce44SJohn Forte 	if (vals->cache_write != 0) {
711fcf3ce44SJohn Forte 		vals->cache_hit += vals->write_hit;
712fcf3ce44SJohn Forte 		factors++;
713fcf3ce44SJohn Forte 	}
714fcf3ce44SJohn Forte 
715fcf3ce44SJohn Forte 	if (vals->cache_hit)
716fcf3ce44SJohn Forte 		vals->cache_hit /= (float)factors;
717fcf3ce44SJohn Forte 
718fcf3ce44SJohn Forte 	/* adjustments */
719fcf3ce44SJohn Forte 	divisor = 1;
720fcf3ce44SJohn Forte 
721fcf3ce44SJohn Forte 	if (flags & SDBC_KBYTES)
722fcf3ce44SJohn Forte 		divisor *= KILOBYTE;
723fcf3ce44SJohn Forte 	if ((flags & SDBC_INTAVG) && (etime > 0))
724fcf3ce44SJohn Forte 		divisor *= etime;
725fcf3ce44SJohn Forte 
726fcf3ce44SJohn Forte 	if (divisor != 1) {
727fcf3ce44SJohn Forte 		vals->cache_read /= divisor;
728fcf3ce44SJohn Forte 		vals->disk_read /= divisor;
729fcf3ce44SJohn Forte 		vals->total_reads /= divisor;
730fcf3ce44SJohn Forte 
731fcf3ce44SJohn Forte 		vals->cache_write /= divisor;
732fcf3ce44SJohn Forte 		vals->disk_write /= divisor;
733fcf3ce44SJohn Forte 		vals->total_writes /= divisor;
734fcf3ce44SJohn Forte 
735fcf3ce44SJohn Forte 		vals->total_cache /= divisor;
736fcf3ce44SJohn Forte 		vals->total_disk /= divisor;
737fcf3ce44SJohn Forte 
738fcf3ce44SJohn Forte 		vals->destaged /= divisor;
739fcf3ce44SJohn Forte 		vals->write_cancellations /= divisor;
740fcf3ce44SJohn Forte 	}
741fcf3ce44SJohn Forte 
742fcf3ce44SJohn Forte 	return (0);
743fcf3ce44SJohn Forte }
744fcf3ce44SJohn Forte 
745fcf3ce44SJohn Forte /*
746fcf3ce44SJohn Forte  * sdbc_getdelta() - calculates the difference between two kstat fields
747fcf3ce44SJohn Forte  *
748fcf3ce44SJohn Forte  * parameters
749fcf3ce44SJohn Forte  * 	sdbcstat_t *sdbcstat - the SDBC stat strcture containing the two fields
750fcf3ce44SJohn Forte  * 	char *name - the name of the fields
751fcf3ce44SJohn Forte  * returns
752fcf3ce44SJohn Forte  * 	uint32_t value of the differences adjusted for overflow of the data type
753fcf3ce44SJohn Forte  */
754fcf3ce44SJohn Forte uint32_t
sdbc_getdelta(sdbcstat_t * sdbcstat,char * name)755fcf3ce44SJohn Forte sdbc_getdelta(sdbcstat_t *sdbcstat, char *name)
756fcf3ce44SJohn Forte {
757fcf3ce44SJohn Forte 	uint32_t *cur_val;
758fcf3ce44SJohn Forte 	uint32_t *pre_val;
759fcf3ce44SJohn Forte 
760fcf3ce44SJohn Forte 	pre_val = kstat_value(sdbcstat->pre_set, name);
761fcf3ce44SJohn Forte 	cur_val = kstat_value(sdbcstat->cur_set, name);
762fcf3ce44SJohn Forte 
763fcf3ce44SJohn Forte 	return (u32_delta(*pre_val, *cur_val));
764fcf3ce44SJohn Forte }
765fcf3ce44SJohn Forte 
766fcf3ce44SJohn Forte void
center(int size,char * hdr)767fcf3ce44SJohn Forte center(int size, char *hdr)
768fcf3ce44SJohn Forte {
769fcf3ce44SJohn Forte 	int lpad = 0;
770fcf3ce44SJohn Forte 	int rpad = 0;
771fcf3ce44SJohn Forte 	char fmt[10];
772fcf3ce44SJohn Forte 
773fcf3ce44SJohn Forte 	if (size == 0)
774fcf3ce44SJohn Forte 		return;
775fcf3ce44SJohn Forte 
776fcf3ce44SJohn Forte 	if (strlen(hdr) < size) {
777fcf3ce44SJohn Forte 		lpad = (size - strlen(hdr)) / 2;
778fcf3ce44SJohn Forte 
779fcf3ce44SJohn Forte 		if (lpad * 2 < size)
780fcf3ce44SJohn Forte 			lpad++;
781fcf3ce44SJohn Forte 
782fcf3ce44SJohn Forte 		rpad = size - (lpad + strlen(hdr));
783fcf3ce44SJohn Forte 	}
784fcf3ce44SJohn Forte 
785fcf3ce44SJohn Forte output:
786fcf3ce44SJohn Forte 	(void) sprintf(fmt, "%%%ds%%s%%%ds", lpad, rpad);
787fcf3ce44SJohn Forte 	(void) printf(fmt, " ", hdr, " ");
788fcf3ce44SJohn Forte }
789