xref: /onnv-gate/usr/src/cmd/fs.d/cachefs/cachefslog/cachefslog.c (revision 633:04519cb7de3b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
23*633Sgt29601  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <stdio.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <stdarg.h>
330Sstevel@tonic-gate #include <libintl.h>
340Sstevel@tonic-gate #include <sys/types.h>
350Sstevel@tonic-gate #include <sys/ioctl.h>
360Sstevel@tonic-gate #include <kstat.h>
370Sstevel@tonic-gate #include <locale.h>
380Sstevel@tonic-gate #include <sys/fs/cachefs_log.h>
390Sstevel@tonic-gate #include "stats.h"
400Sstevel@tonic-gate 
410Sstevel@tonic-gate void usage(char *);
420Sstevel@tonic-gate void pr_err(char *, ...);
430Sstevel@tonic-gate 
440Sstevel@tonic-gate static int hflag = 0;
450Sstevel@tonic-gate static char *fpath = NULL;
460Sstevel@tonic-gate static int vflag = 0;
470Sstevel@tonic-gate char *prog;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate static void log_show(char *, char *);
500Sstevel@tonic-gate 
510Sstevel@tonic-gate int
main(int argc,char ** argv)520Sstevel@tonic-gate main(int argc, char **argv)
530Sstevel@tonic-gate {
540Sstevel@tonic-gate 	int rc = 0, c;
550Sstevel@tonic-gate 	int errflg = 0;
560Sstevel@tonic-gate 	stats_cookie_t *fs = NULL;
570Sstevel@tonic-gate 	char *logfile;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
600Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
610Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
620Sstevel@tonic-gate #endif /* TEXT_DOMAIN */
630Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	if (prog = strrchr(argv[0], '/'))
660Sstevel@tonic-gate 		++prog;
670Sstevel@tonic-gate 	else
680Sstevel@tonic-gate 		prog = argv[0];
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "hf:v")) != EOF)
710Sstevel@tonic-gate 		switch (c) {
720Sstevel@tonic-gate 		case 'h':
730Sstevel@tonic-gate 			if (fpath != NULL)
740Sstevel@tonic-gate 				++errflg;
750Sstevel@tonic-gate 			else
760Sstevel@tonic-gate 				++hflag;
770Sstevel@tonic-gate 			break;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 		case 'f':
800Sstevel@tonic-gate 			if (hflag)
810Sstevel@tonic-gate 				++errflg;
820Sstevel@tonic-gate 			else
830Sstevel@tonic-gate 				fpath = optarg;
840Sstevel@tonic-gate 			break;
850Sstevel@tonic-gate 
860Sstevel@tonic-gate 		case 'v':
870Sstevel@tonic-gate 			++vflag;
880Sstevel@tonic-gate 			break;
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 		case '?':
910Sstevel@tonic-gate 		default:
920Sstevel@tonic-gate 			++errflg;
930Sstevel@tonic-gate 			break;
940Sstevel@tonic-gate 		}
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	if ((errflg) || (optind != (argc - 1))) {
970Sstevel@tonic-gate 		usage(NULL);
980Sstevel@tonic-gate 		rc = -1;
990Sstevel@tonic-gate 		goto out;
1000Sstevel@tonic-gate 	}
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	fs = stats_create_mountpath(argv[optind], prog);
1030Sstevel@tonic-gate 	if (fs == NULL) {
1040Sstevel@tonic-gate 		pr_err(gettext("Cannot initialize cachefs library\n"));
1050Sstevel@tonic-gate 		rc = 1;
1060Sstevel@tonic-gate 		goto out;
1070Sstevel@tonic-gate 	}
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	if (! stats_good(fs)) {
1100Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
1110Sstevel@tonic-gate 		rc = stats_errno(fs);
1120Sstevel@tonic-gate 		goto out;
1130Sstevel@tonic-gate 	}
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	if ((logfile = stats_log_kernel_getname(fs)) == NULL) {
1160Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
1170Sstevel@tonic-gate 		rc = stats_errno(fs);
1180Sstevel@tonic-gate 		goto out;
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 	if ((logfile[0] == '\0') && (hflag) && (! vflag)) {
1210Sstevel@tonic-gate 		log_show(argv[optind], logfile);
1220Sstevel@tonic-gate 		goto out;
1230Sstevel@tonic-gate 	}
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	if (fpath != NULL) {
1260Sstevel@tonic-gate 		if ((stats_log_kernel_setname(fs, fpath) != 0) ||
1270Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_MOUNT, 1) != 0) ||
1280Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_UMOUNT, 1) != 0) ||
1290Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_REMOVE, 1) != 0) ||
1300Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_RMDIR, 1) != 0) ||
1310Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_TRUNCATE, 1) != 0) ||
1320Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_CREATE, 1) != 0) ||
1330Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_MKDIR, 1) != 0) ||
1340Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_RENAME, 1) != 0) ||
1350Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_SYMLINK, 1) != 0) ||
1360Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_UALLOC, 1) != 0) ||
1370Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_CSYMLINK, 1) != 0) ||
1380Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_FILLDIR, 1) != 0) ||
1390Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_MDCREATE, 1) != 0) ||
1400Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_NOCACHE, 1) != 0) ||
1410Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_CALLOC, 1) != 0) ||
1420Sstevel@tonic-gate 		    (stats_log_which(fs, CACHEFS_LOG_RFDIR, 1) != 0)) {
1430Sstevel@tonic-gate 			pr_err(stats_errorstr(fs));
1440Sstevel@tonic-gate 			rc = stats_errno(fs);
1450Sstevel@tonic-gate 			goto out;
1460Sstevel@tonic-gate 		}
1470Sstevel@tonic-gate 	} else if (hflag) {
1480Sstevel@tonic-gate 		if (stats_log_kernel_setname(fs, NULL) != 0) {
1490Sstevel@tonic-gate 			pr_err(stats_errorstr(fs));
1500Sstevel@tonic-gate 			rc = stats_errno(fs);
1510Sstevel@tonic-gate 			goto out;
1520Sstevel@tonic-gate 		}
1530Sstevel@tonic-gate 	}
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	if ((logfile = stats_log_kernel_getname(fs)) == NULL) {
1560Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
1570Sstevel@tonic-gate 		rc = stats_errno(fs);
1580Sstevel@tonic-gate 		goto out;
1590Sstevel@tonic-gate 	}
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	log_show(argv[optind], logfile);
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	/*
1640Sstevel@tonic-gate 	 * if they're changing state, inform them of other filesystems
1650Sstevel@tonic-gate 	 * that they're changing state for by way of sharing the
1660Sstevel@tonic-gate 	 * cache.
1670Sstevel@tonic-gate 	 *
1680Sstevel@tonic-gate 	 * or, if they're verbose (-v flag), tell them about the
1690Sstevel@tonic-gate 	 * others.
1700Sstevel@tonic-gate 	 */
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	if (((fpath) || (hflag) || (vflag)) && (! stats_inerror(fs))) {
1730Sstevel@tonic-gate 		cachefs_kstat_key_t *k, *origk;
1740Sstevel@tonic-gate 		stats_cookie_t *sc;
1750Sstevel@tonic-gate 		int before = 0;
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 		origk = stats_getkey(fs);
1780Sstevel@tonic-gate 		sc = stats_create_unbound(prog);
1790Sstevel@tonic-gate 		if (sc == NULL) {
1800Sstevel@tonic-gate 			pr_err(gettext("Cannot create stats object"));
1810Sstevel@tonic-gate 			rc = 1;
1820Sstevel@tonic-gate 			goto out;
1830Sstevel@tonic-gate 		}
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 		while ((k = stats_next(sc)) != NULL) {
1860Sstevel@tonic-gate 			if (! k->ks_mounted) {
1870Sstevel@tonic-gate 				free(k);
1880Sstevel@tonic-gate 				continue;
1890Sstevel@tonic-gate 			}
190*633Sgt29601 			if (strcmp((char *)(uintptr_t)origk->ks_cachedir,
191*633Sgt29601 				(char *)(uintptr_t)k->ks_cachedir) != 0) {
1920Sstevel@tonic-gate 				free(k);
1930Sstevel@tonic-gate 				continue;
1940Sstevel@tonic-gate 			}
1950Sstevel@tonic-gate 			if (origk->ks_id == k->ks_id) {
1960Sstevel@tonic-gate 				free(k);
1970Sstevel@tonic-gate 				continue;
1980Sstevel@tonic-gate 			}
1990Sstevel@tonic-gate 			if (! before)
2000Sstevel@tonic-gate 				printf("\n");
2010Sstevel@tonic-gate 			before = 1;
202*633Sgt29601 			log_show((char *)(uintptr_t)k->ks_mountpoint, logfile);
2030Sstevel@tonic-gate 			free(k);
2040Sstevel@tonic-gate 		}
2050Sstevel@tonic-gate 		free(origk);
2060Sstevel@tonic-gate 		stats_destroy(sc);
2070Sstevel@tonic-gate 	}
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	if (stats_inerror(fs)) {
2100Sstevel@tonic-gate 		pr_err(stats_errorstr(fs));
2110Sstevel@tonic-gate 		rc = stats_errno(fs);
2120Sstevel@tonic-gate 	}
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate out:
2150Sstevel@tonic-gate 	stats_destroy(fs);
2160Sstevel@tonic-gate 	return (rc);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate static void
log_show(char * mount,char * logfile)2200Sstevel@tonic-gate log_show(char *mount, char *logfile)
2210Sstevel@tonic-gate {
2220Sstevel@tonic-gate 	if (logfile[0] == '\0')
2230Sstevel@tonic-gate 		logfile = gettext("not logged");
2240Sstevel@tonic-gate 	printf("%s: %s\n", logfile, mount);
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate /*
2280Sstevel@tonic-gate  *
2290Sstevel@tonic-gate  *			usage
2300Sstevel@tonic-gate  *
2310Sstevel@tonic-gate  * Description:
2320Sstevel@tonic-gate  *	Prints a short usage message.
2330Sstevel@tonic-gate  * Arguments:
2340Sstevel@tonic-gate  *	msgp	message to include with the usage message
2350Sstevel@tonic-gate  * Returns:
2360Sstevel@tonic-gate  * Preconditions:
2370Sstevel@tonic-gate  */
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate void
usage(char * msgp)2400Sstevel@tonic-gate usage(char *msgp)
2410Sstevel@tonic-gate {
2420Sstevel@tonic-gate 	if (msgp) {
2430Sstevel@tonic-gate 		pr_err("%s", msgp);
2440Sstevel@tonic-gate 	}
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate 	fprintf(stderr,
2470Sstevel@tonic-gate 	    gettext("Usage: "
2480Sstevel@tonic-gate 	    "cachefslog [ -v ] [-h | -f <logfile>] mountpoint\n"));
2490Sstevel@tonic-gate }
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate /*
2520Sstevel@tonic-gate  *
2530Sstevel@tonic-gate  *			pr_err
2540Sstevel@tonic-gate  *
2550Sstevel@tonic-gate  * Description:
2560Sstevel@tonic-gate  *	Prints an error message to stderr.
2570Sstevel@tonic-gate  * Arguments:
2580Sstevel@tonic-gate  *	fmt	printf style format
2590Sstevel@tonic-gate  *	...	arguments for fmt
2600Sstevel@tonic-gate  * Returns:
2610Sstevel@tonic-gate  * Preconditions:
2620Sstevel@tonic-gate  *	precond(fmt)
2630Sstevel@tonic-gate  */
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate void
pr_err(char * fmt,...)2660Sstevel@tonic-gate pr_err(char *fmt, ...)
2670Sstevel@tonic-gate {
2680Sstevel@tonic-gate 	va_list ap;
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 	va_start(ap, fmt);
2710Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("cachefslog: "));
2720Sstevel@tonic-gate 	(void) vfprintf(stderr, fmt, ap);
2730Sstevel@tonic-gate 	(void) fprintf(stderr, "\n");
2740Sstevel@tonic-gate 	va_end(ap);
2750Sstevel@tonic-gate }
276