xref: /onnv-gate/usr/src/cmd/fs.d/cachefs/cachefslog/cachefslog.c (revision 0:68f95e015346)
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 <string.h>
32*0Sstevel@tonic-gate #include <stdarg.h>
33*0Sstevel@tonic-gate #include <libintl.h>
34*0Sstevel@tonic-gate #include <sys/types.h>
35*0Sstevel@tonic-gate #include <sys/ioctl.h>
36*0Sstevel@tonic-gate #include <kstat.h>
37*0Sstevel@tonic-gate #include <locale.h>
38*0Sstevel@tonic-gate #include <sys/fs/cachefs_log.h>
39*0Sstevel@tonic-gate #include "stats.h"
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate void usage(char *);
42*0Sstevel@tonic-gate void pr_err(char *, ...);
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate static int hflag = 0;
45*0Sstevel@tonic-gate static char *fpath = NULL;
46*0Sstevel@tonic-gate static int vflag = 0;
47*0Sstevel@tonic-gate char *prog;
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate static void log_show(char *, char *);
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate int
52*0Sstevel@tonic-gate main(int argc, char **argv)
53*0Sstevel@tonic-gate {
54*0Sstevel@tonic-gate 	int rc = 0, c;
55*0Sstevel@tonic-gate 	int errflg = 0;
56*0Sstevel@tonic-gate 	stats_cookie_t *fs = NULL;
57*0Sstevel@tonic-gate 	char *logfile;
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
60*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
61*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
62*0Sstevel@tonic-gate #endif /* TEXT_DOMAIN */
63*0Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	if (prog = strrchr(argv[0], '/'))
66*0Sstevel@tonic-gate 		++prog;
67*0Sstevel@tonic-gate 	else
68*0Sstevel@tonic-gate 		prog = argv[0];
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "hf:v")) != EOF)
71*0Sstevel@tonic-gate 		switch (c) {
72*0Sstevel@tonic-gate 		case 'h':
73*0Sstevel@tonic-gate 			if (fpath != NULL)
74*0Sstevel@tonic-gate 				++errflg;
75*0Sstevel@tonic-gate 			else
76*0Sstevel@tonic-gate 				++hflag;
77*0Sstevel@tonic-gate 			break;
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate 		case 'f':
80*0Sstevel@tonic-gate 			if (hflag)
81*0Sstevel@tonic-gate 				++errflg;
82*0Sstevel@tonic-gate 			else
83*0Sstevel@tonic-gate 				fpath = optarg;
84*0Sstevel@tonic-gate 			break;
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 		case 'v':
87*0Sstevel@tonic-gate 			++vflag;
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) || (optind != (argc - 1))) {
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 	fs = stats_create_mountpath(argv[optind], prog);
103*0Sstevel@tonic-gate 	if (fs == NULL) {
104*0Sstevel@tonic-gate 		pr_err(gettext("Cannot initialize cachefs library\n"));
105*0Sstevel@tonic-gate 		rc = 1;
106*0Sstevel@tonic-gate 		goto out;
107*0Sstevel@tonic-gate 	}
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate 	if (! stats_good(fs)) {
110*0Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
111*0Sstevel@tonic-gate 		rc = stats_errno(fs);
112*0Sstevel@tonic-gate 		goto out;
113*0Sstevel@tonic-gate 	}
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	if ((logfile = stats_log_kernel_getname(fs)) == NULL) {
116*0Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
117*0Sstevel@tonic-gate 		rc = stats_errno(fs);
118*0Sstevel@tonic-gate 		goto out;
119*0Sstevel@tonic-gate 	}
120*0Sstevel@tonic-gate 	if ((logfile[0] == '\0') && (hflag) && (! vflag)) {
121*0Sstevel@tonic-gate 		log_show(argv[optind], logfile);
122*0Sstevel@tonic-gate 		goto out;
123*0Sstevel@tonic-gate 	}
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 	if (fpath != NULL) {
126*0Sstevel@tonic-gate 		if ((stats_log_kernel_setname(fs, fpath) != 0) ||
127*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_MOUNT, 1) != 0) ||
128*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_UMOUNT, 1) != 0) ||
129*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_REMOVE, 1) != 0) ||
130*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_RMDIR, 1) != 0) ||
131*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_TRUNCATE, 1) != 0) ||
132*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_CREATE, 1) != 0) ||
133*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_MKDIR, 1) != 0) ||
134*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_RENAME, 1) != 0) ||
135*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_SYMLINK, 1) != 0) ||
136*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_UALLOC, 1) != 0) ||
137*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_CSYMLINK, 1) != 0) ||
138*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_FILLDIR, 1) != 0) ||
139*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_MDCREATE, 1) != 0) ||
140*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_NOCACHE, 1) != 0) ||
141*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_CALLOC, 1) != 0) ||
142*0Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_RFDIR, 1) != 0)) {
143*0Sstevel@tonic-gate 			pr_err(stats_errorstr(fs));
144*0Sstevel@tonic-gate 			rc = stats_errno(fs);
145*0Sstevel@tonic-gate 			goto out;
146*0Sstevel@tonic-gate 		}
147*0Sstevel@tonic-gate 	} else if (hflag) {
148*0Sstevel@tonic-gate 		if (stats_log_kernel_setname(fs, NULL) != 0) {
149*0Sstevel@tonic-gate 			pr_err(stats_errorstr(fs));
150*0Sstevel@tonic-gate 			rc = stats_errno(fs);
151*0Sstevel@tonic-gate 			goto out;
152*0Sstevel@tonic-gate 		}
153*0Sstevel@tonic-gate 	}
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 	if ((logfile = stats_log_kernel_getname(fs)) == NULL) {
156*0Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
157*0Sstevel@tonic-gate 		rc = stats_errno(fs);
158*0Sstevel@tonic-gate 		goto out;
159*0Sstevel@tonic-gate 	}
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 	log_show(argv[optind], logfile);
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate 	/*
164*0Sstevel@tonic-gate 	 * if they're changing state, inform them of other filesystems
165*0Sstevel@tonic-gate 	 * that they're changing state for by way of sharing the
166*0Sstevel@tonic-gate 	 * cache.
167*0Sstevel@tonic-gate 	 *
168*0Sstevel@tonic-gate 	 * or, if they're verbose (-v flag), tell them about the
169*0Sstevel@tonic-gate 	 * others.
170*0Sstevel@tonic-gate 	 */
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate 	if (((fpath) || (hflag) || (vflag)) && (! stats_inerror(fs))) {
173*0Sstevel@tonic-gate 		cachefs_kstat_key_t *k, *origk;
174*0Sstevel@tonic-gate 		stats_cookie_t *sc;
175*0Sstevel@tonic-gate 		int before = 0;
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 		origk = stats_getkey(fs);
178*0Sstevel@tonic-gate 		sc = stats_create_unbound(prog);
179*0Sstevel@tonic-gate 		if (sc == NULL) {
180*0Sstevel@tonic-gate 			pr_err(gettext("Cannot create stats object"));
181*0Sstevel@tonic-gate 			rc = 1;
182*0Sstevel@tonic-gate 			goto out;
183*0Sstevel@tonic-gate 		}
184*0Sstevel@tonic-gate 
185*0Sstevel@tonic-gate 		while ((k = stats_next(sc)) != NULL) {
186*0Sstevel@tonic-gate 			if (! k->ks_mounted) {
187*0Sstevel@tonic-gate 				free(k);
188*0Sstevel@tonic-gate 				continue;
189*0Sstevel@tonic-gate 			}
190*0Sstevel@tonic-gate 			if (strcmp((char *)origk->ks_cachedir,
191*0Sstevel@tonic-gate 				(char *)k->ks_cachedir) != 0) {
192*0Sstevel@tonic-gate 				free(k);
193*0Sstevel@tonic-gate 				continue;
194*0Sstevel@tonic-gate 			}
195*0Sstevel@tonic-gate 			if (origk->ks_id == k->ks_id) {
196*0Sstevel@tonic-gate 				free(k);
197*0Sstevel@tonic-gate 				continue;
198*0Sstevel@tonic-gate 			}
199*0Sstevel@tonic-gate 			if (! before)
200*0Sstevel@tonic-gate 				printf("\n");
201*0Sstevel@tonic-gate 			before = 1;
202*0Sstevel@tonic-gate 			log_show((char *)k->ks_mountpoint, logfile);
203*0Sstevel@tonic-gate 			free(k);
204*0Sstevel@tonic-gate 		}
205*0Sstevel@tonic-gate 		free(origk);
206*0Sstevel@tonic-gate 		stats_destroy(sc);
207*0Sstevel@tonic-gate 	}
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate 	if (stats_inerror(fs)) {
210*0Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
211*0Sstevel@tonic-gate 		rc = stats_errno(fs);
212*0Sstevel@tonic-gate 	}
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate out:
215*0Sstevel@tonic-gate 	stats_destroy(fs);
216*0Sstevel@tonic-gate 	return (rc);
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate static void
220*0Sstevel@tonic-gate log_show(char *mount, char *logfile)
221*0Sstevel@tonic-gate {
222*0Sstevel@tonic-gate 	if (logfile[0] == '\0')
223*0Sstevel@tonic-gate 		logfile = gettext("not logged");
224*0Sstevel@tonic-gate 	printf("%s: %s\n", logfile, mount);
225*0Sstevel@tonic-gate }
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate /*
228*0Sstevel@tonic-gate  *
229*0Sstevel@tonic-gate  *			usage
230*0Sstevel@tonic-gate  *
231*0Sstevel@tonic-gate  * Description:
232*0Sstevel@tonic-gate  *	Prints a short usage message.
233*0Sstevel@tonic-gate  * Arguments:
234*0Sstevel@tonic-gate  *	msgp	message to include with the usage message
235*0Sstevel@tonic-gate  * Returns:
236*0Sstevel@tonic-gate  * Preconditions:
237*0Sstevel@tonic-gate  */
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate void
240*0Sstevel@tonic-gate usage(char *msgp)
241*0Sstevel@tonic-gate {
242*0Sstevel@tonic-gate 	if (msgp) {
243*0Sstevel@tonic-gate 		pr_err("%s", msgp);
244*0Sstevel@tonic-gate 	}
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 	fprintf(stderr,
247*0Sstevel@tonic-gate 	    gettext("Usage: "
248*0Sstevel@tonic-gate 	    "cachefslog [ -v ] [-h | -f <logfile>] mountpoint\n"));
249*0Sstevel@tonic-gate }
250*0Sstevel@tonic-gate 
251*0Sstevel@tonic-gate /*
252*0Sstevel@tonic-gate  *
253*0Sstevel@tonic-gate  *			pr_err
254*0Sstevel@tonic-gate  *
255*0Sstevel@tonic-gate  * Description:
256*0Sstevel@tonic-gate  *	Prints an error message to stderr.
257*0Sstevel@tonic-gate  * Arguments:
258*0Sstevel@tonic-gate  *	fmt	printf style format
259*0Sstevel@tonic-gate  *	...	arguments for fmt
260*0Sstevel@tonic-gate  * Returns:
261*0Sstevel@tonic-gate  * Preconditions:
262*0Sstevel@tonic-gate  *	precond(fmt)
263*0Sstevel@tonic-gate  */
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate void
266*0Sstevel@tonic-gate pr_err(char *fmt, ...)
267*0Sstevel@tonic-gate {
268*0Sstevel@tonic-gate 	va_list ap;
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 	va_start(ap, fmt);
271*0Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("cachefslog: "));
272*0Sstevel@tonic-gate 	(void) vfprintf(stderr, fmt, ap);
273*0Sstevel@tonic-gate 	(void) fprintf(stderr, "\n");
274*0Sstevel@tonic-gate 	va_end(ap);
275*0Sstevel@tonic-gate }
276