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