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