1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <stdarg.h>
32*0Sstevel@tonic-gate #include <libintl.h>
33*0Sstevel@tonic-gate #include <sys/types.h>
34*0Sstevel@tonic-gate #include <sys/ioctl.h>
35*0Sstevel@tonic-gate #include <kstat.h>
36*0Sstevel@tonic-gate #include <sys/fs/cachefs_log.h>
37*0Sstevel@tonic-gate #include <string.h>
38*0Sstevel@tonic-gate #include <assert.h>
39*0Sstevel@tonic-gate #include <ndbm.h>
40*0Sstevel@tonic-gate #include <malloc.h>
41*0Sstevel@tonic-gate #include <locale.h>
42*0Sstevel@tonic-gate #include "stats.h"
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate void usage(char *);
45*0Sstevel@tonic-gate void pr_err(char *, ...);
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate static int aflag = 0;
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate int
main(int argc,char ** argv)50*0Sstevel@tonic-gate main(int argc, char **argv)
51*0Sstevel@tonic-gate {
52*0Sstevel@tonic-gate 	int rc = 0;
53*0Sstevel@tonic-gate 	int c, errflg = 0;
54*0Sstevel@tonic-gate 	int len1, len2;
55*0Sstevel@tonic-gate 	char *ar, *progname;
56*0Sstevel@tonic-gate 	void *record;
57*0Sstevel@tonic-gate 	caddr_t vfsp;
58*0Sstevel@tonic-gate 	char *path;
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 	stats_cookie_t *sc = NULL;
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate 	datum key;
63*0Sstevel@tonic-gate 	struct cachefs_log_logfile_header *lh;
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	mount_info *mip;
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
68*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
69*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
70*0Sstevel@tonic-gate #endif /* TEXT_DOMAIN */
71*0Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate 	if (progname = strrchr(argv[0], '/'))
74*0Sstevel@tonic-gate 		++progname;
75*0Sstevel@tonic-gate 	else
76*0Sstevel@tonic-gate 		progname = argv[0];
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate 	if ((sc = stats_create_unbound(progname)) == NULL) {
79*0Sstevel@tonic-gate 		pr_err(gettext("Cannot initialize stats library\n"));
80*0Sstevel@tonic-gate 		rc = 1;
81*0Sstevel@tonic-gate 		goto out;
82*0Sstevel@tonic-gate 	}
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "a")) != EOF)
85*0Sstevel@tonic-gate 		switch (c) {
86*0Sstevel@tonic-gate 		case 'a':
87*0Sstevel@tonic-gate 			++aflag;
88*0Sstevel@tonic-gate 			break;
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 		case '?':
91*0Sstevel@tonic-gate 		default:
92*0Sstevel@tonic-gate 			++errflg;
93*0Sstevel@tonic-gate 			break;
94*0Sstevel@tonic-gate 		}
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 	if (errflg) {
97*0Sstevel@tonic-gate 		usage(NULL);
98*0Sstevel@tonic-gate 		rc = -1;
99*0Sstevel@tonic-gate 		goto out;
100*0Sstevel@tonic-gate 	}
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	path = argv[optind];
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	if (stats_log_logfile_open(sc, path) != 0) {
105*0Sstevel@tonic-gate 		pr_err(stats_errorstr(sc));
106*0Sstevel@tonic-gate 		rc = 1;
107*0Sstevel@tonic-gate 		goto out;
108*0Sstevel@tonic-gate 	}
109*0Sstevel@tonic-gate 	lh = stats_log_getheader(sc);
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 	if (lh->lh_errno != 0)
112*0Sstevel@tonic-gate 		printf(gettext("warning: problem writing logfile: %s\n\n"),
113*0Sstevel@tonic-gate 		    strerror(lh->lh_errno));
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	if (aflag) {
116*0Sstevel@tonic-gate 		while (record = stats_log_logfile_read(sc, NULL)) {
117*0Sstevel@tonic-gate 			ar = stats_log_record_toascii(sc, record);
118*0Sstevel@tonic-gate 			if (ar == NULL)
119*0Sstevel@tonic-gate 				break;
120*0Sstevel@tonic-gate 			puts(ar);
121*0Sstevel@tonic-gate 			free(record);
122*0Sstevel@tonic-gate 		}
123*0Sstevel@tonic-gate 		if (stats_inerror(sc))
124*0Sstevel@tonic-gate 			pr_err(stats_errorstr(sc));
125*0Sstevel@tonic-gate 		goto out;
126*0Sstevel@tonic-gate 	}
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate 	stats_dbm_open(sc);
129*0Sstevel@tonic-gate 	stats_dbm_rm(sc);
130*0Sstevel@tonic-gate 	if (stats_inerror(sc)) {
131*0Sstevel@tonic-gate 		pr_err(stats_errorstr(sc));
132*0Sstevel@tonic-gate 		rc = stats_errno(sc);
133*0Sstevel@tonic-gate 		goto out;
134*0Sstevel@tonic-gate 	}
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate 	stats_log_compute_wssize(sc);
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 	if (stats_inerror(sc)) {
139*0Sstevel@tonic-gate 		pr_err(stats_errorstr(sc));
140*0Sstevel@tonic-gate 		rc = stats_errno(sc);
141*0Sstevel@tonic-gate 		goto out;
142*0Sstevel@tonic-gate 	}
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate 	for (key = stats_dbm_firstkey(sc);
145*0Sstevel@tonic-gate 	    key.dptr != NULL;
146*0Sstevel@tonic-gate 	    key = stats_dbm_nextkey(sc)) {
147*0Sstevel@tonic-gate 		if (key.dsize != sizeof (vfsp))
148*0Sstevel@tonic-gate 			continue;
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 		memcpy((caddr_t) &vfsp, key.dptr, sizeof (vfsp));
151*0Sstevel@tonic-gate 		mip = stats_dbm_fetch_byvfsp(sc, vfsp);
152*0Sstevel@tonic-gate 		if (mip == NULL)
153*0Sstevel@tonic-gate 			continue;
154*0Sstevel@tonic-gate 		if (! mip->mi_used)
155*0Sstevel@tonic-gate 			continue;
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate 		printf("\n    %s\n", mip->mi_path);
158*0Sstevel@tonic-gate 		if (! mip->mi_mounted)
159*0Sstevel@tonic-gate 			printf("    (currently unmounted)\n");
160*0Sstevel@tonic-gate 		printf("\t       end size: %17lldk\n", mip->mi_current / 1024);
161*0Sstevel@tonic-gate 		printf("\thigh water size: %17lldk\n", mip->mi_high / 1024);
162*0Sstevel@tonic-gate 		free(mip);
163*0Sstevel@tonic-gate 	}
164*0Sstevel@tonic-gate 
165*0Sstevel@tonic-gate 	printf(gettext("\n    total for cache\n"));
166*0Sstevel@tonic-gate 	printf(gettext("\t   initial size: %17lldk\n"),
167*0Sstevel@tonic-gate 	    (u_offset_t)(stats_log_wssize_init(sc) *
168*0Sstevel@tonic-gate 		lh->lh_maxbsize / (u_offset_t) 1024));
169*0Sstevel@tonic-gate 	printf(gettext("\t       end size: %17lldk\n"),
170*0Sstevel@tonic-gate 	    (u_offset_t)(stats_log_wssize_current(sc) / 1024));
171*0Sstevel@tonic-gate 	printf(gettext("\thigh water size: %17lldk\n"),
172*0Sstevel@tonic-gate 	    (u_offset_t)(stats_log_wssize_high(sc) / 1024));
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 	if (stats_inerror(sc)) {
175*0Sstevel@tonic-gate 		pr_err(stats_errorstr(sc));
176*0Sstevel@tonic-gate 		rc = stats_errno(sc);
177*0Sstevel@tonic-gate 	}
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate out:
180*0Sstevel@tonic-gate 	stats_dbm_close(sc);
181*0Sstevel@tonic-gate 	stats_destroy(sc);
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	return (rc);
184*0Sstevel@tonic-gate }
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate /*
187*0Sstevel@tonic-gate  *
188*0Sstevel@tonic-gate  *			usage
189*0Sstevel@tonic-gate  *
190*0Sstevel@tonic-gate  * Description:
191*0Sstevel@tonic-gate  *	Prints a short usage message.
192*0Sstevel@tonic-gate  * Arguments:
193*0Sstevel@tonic-gate  *	msgp	message to include with the usage message
194*0Sstevel@tonic-gate  * Returns:
195*0Sstevel@tonic-gate  * Preconditions:
196*0Sstevel@tonic-gate  */
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate void
usage(char * msgp)199*0Sstevel@tonic-gate usage(char *msgp)
200*0Sstevel@tonic-gate {
201*0Sstevel@tonic-gate 	if (msgp) {
202*0Sstevel@tonic-gate 		pr_err("%s", msgp);
203*0Sstevel@tonic-gate 	}
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	fprintf(stderr,
206*0Sstevel@tonic-gate 	    gettext("Usage: cachefswssize logfile\n"));
207*0Sstevel@tonic-gate }
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate /*
210*0Sstevel@tonic-gate  *
211*0Sstevel@tonic-gate  *			pr_err
212*0Sstevel@tonic-gate  *
213*0Sstevel@tonic-gate  * Description:
214*0Sstevel@tonic-gate  *	Prints an error message to stderr.
215*0Sstevel@tonic-gate  * Arguments:
216*0Sstevel@tonic-gate  *	fmt	printf style format
217*0Sstevel@tonic-gate  *	...	arguments for fmt
218*0Sstevel@tonic-gate  * Returns:
219*0Sstevel@tonic-gate  * Preconditions:
220*0Sstevel@tonic-gate  *	precond(fmt)
221*0Sstevel@tonic-gate  */
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate void
pr_err(char * fmt,...)224*0Sstevel@tonic-gate pr_err(char *fmt, ...)
225*0Sstevel@tonic-gate {
226*0Sstevel@tonic-gate 	va_list ap;
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	va_start(ap, fmt);
229*0Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("cachefswssize: "));
230*0Sstevel@tonic-gate 	(void) vfprintf(stderr, fmt, ap);
231*0Sstevel@tonic-gate 	(void) fprintf(stderr, "\n");
232*0Sstevel@tonic-gate 	va_end(ap);
233*0Sstevel@tonic-gate }
234