00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef lint
00013 static const char copyright[] =
00014 "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
00015 #endif
00016
00017 #ifndef NO_SYSTEM_INCLUDES
00018 #include <sys/types.h>
00019
00020 #if TIME_WITH_SYS_TIME
00021 #include <sys/time.h>
00022 #include <time.h>
00023 #else
00024 #if HAVE_SYS_TIME_H
00025 #include <sys/time.h>
00026 #else
00027 #include <time.h>
00028 #endif
00029 #endif
00030
00031 #include <ctype.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035 #endif
00036
00037 #include "db_int.h"
00038 #include "dbinc/db_page.h"
00039
00040 typedef enum { T_NOTSET,
00041 T_DB, T_ENV, T_LOCK, T_LOG, T_MPOOL, T_MUTEX, T_REP, T_TXN } test_t;
00042
00043 int db_stat_db_init __P((DB_ENV *, char *, test_t, u_int32_t, int *));
00044 int db_stat_main __P((int, char *[]));
00045 int db_stat_usage __P((void));
00046 int db_stat_version_check __P((void));
00047
00048 const char *progname;
00049
00050 int
00051 db_stat(args)
00052 char *args;
00053 {
00054 int argc;
00055 char **argv;
00056
00057 __db_util_arg("db_stat", args, &argc, &argv);
00058 return (db_stat_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);
00059 }
00060
00061 #include <stdio.h>
00062 #define ERROR_RETURN ERROR
00063
00064 int
00065 db_stat_main(argc, argv)
00066 int argc;
00067 char *argv[];
00068 {
00069 extern char *optarg;
00070 extern int optind, __db_getopt_reset;
00071 DB_ENV *dbenv;
00072 DB_BTREE_STAT *sp;
00073 DB *alt_dbp, *dbp;
00074 test_t ttype;
00075 u_int32_t cache, env_flags, fast, flags;
00076 int ch, exitval;
00077 int nflag, private, resize, ret;
00078 char *db, *home, *p, *passwd, *subdb;
00079
00080 if ((progname = strrchr(argv[0], '/')) == NULL)
00081 progname = argv[0];
00082 else
00083 ++progname;
00084
00085 if ((ret = db_stat_version_check()) != 0)
00086 return (ret);
00087
00088 dbenv = NULL;
00089 dbp = NULL;
00090 ttype = T_NOTSET;
00091 cache = MEGABYTE;
00092 exitval = fast = flags = nflag = private = 0;
00093 db = home = passwd = subdb = NULL;
00094 env_flags = 0;
00095
00096 __db_getopt_reset = 1;
00097 while ((ch = getopt(argc,
00098 argv, "C:cd:Eefh:L:lM:mNP:R:rs:tVxX:Z")) != EOF)
00099 switch (ch) {
00100 case 'C': case 'c':
00101 if (ttype != T_NOTSET && ttype != T_LOCK)
00102 goto argcombo;
00103 ttype = T_LOCK;
00104 if (ch != 'c')
00105 for (p = optarg; *p; ++p)
00106 switch (*p) {
00107 case 'A':
00108 LF_SET(DB_STAT_ALL);
00109 break;
00110 case 'c':
00111 LF_SET(DB_STAT_LOCK_CONF);
00112 break;
00113 case 'l':
00114 LF_SET(DB_STAT_LOCK_LOCKERS);
00115 break;
00116 case 'm':
00117 break;
00118 case 'o':
00119 LF_SET(DB_STAT_LOCK_OBJECTS);
00120 break;
00121 case 'p':
00122 LF_SET(DB_STAT_LOCK_PARAMS);
00123 break;
00124 default:
00125 return (db_stat_usage());
00126 }
00127 break;
00128 case 'd':
00129 if (ttype != T_NOTSET && ttype != T_DB)
00130 goto argcombo;
00131 ttype = T_DB;
00132 db = optarg;
00133 break;
00134 case 'E': case 'e':
00135 if (ttype != T_NOTSET && ttype != T_ENV)
00136 goto argcombo;
00137 ttype = T_ENV;
00138 LF_SET(DB_STAT_SUBSYSTEM);
00139 if (ch == 'E')
00140 LF_SET(DB_STAT_ALL);
00141 break;
00142 case 'f':
00143 fast = DB_FAST_STAT;
00144 break;
00145 case 'h':
00146 home = optarg;
00147 break;
00148 case 'L': case 'l':
00149 if (ttype != T_NOTSET && ttype != T_LOG)
00150 goto argcombo;
00151 ttype = T_LOG;
00152 if (ch != 'l')
00153 for (p = optarg; *p; ++p)
00154 switch (*p) {
00155 case 'A':
00156 LF_SET(DB_STAT_ALL);
00157 break;
00158 default:
00159 return (db_stat_usage());
00160 }
00161 break;
00162 case 'M': case 'm':
00163 if (ttype != T_NOTSET && ttype != T_MPOOL)
00164 goto argcombo;
00165 ttype = T_MPOOL;
00166 if (ch != 'm')
00167 for (p = optarg; *p; ++p)
00168 switch (*p) {
00169 case 'A':
00170 LF_SET(DB_STAT_ALL);
00171 break;
00172 case 'h':
00173 LF_SET(DB_STAT_MEMP_HASH);
00174 break;
00175 case 'm':
00176 break;
00177 default:
00178 return (db_stat_usage());
00179 }
00180 break;
00181 case 'N':
00182 nflag = 1;
00183 break;
00184 case 'P':
00185 passwd = strdup(optarg);
00186 memset(optarg, 0, strlen(optarg));
00187 if (passwd == NULL) {
00188 fprintf(stderr, "%s: strdup: %s\n",
00189 progname, strerror(errno));
00190 return (EXIT_FAILURE);
00191 }
00192 break;
00193 case 'R': case 'r':
00194 if (ttype != T_NOTSET && ttype != T_REP)
00195 goto argcombo;
00196 ttype = T_REP;
00197 if (ch != 'r')
00198 for (p = optarg; *p; ++p)
00199 switch (*p) {
00200 case 'A':
00201 LF_SET(DB_STAT_ALL);
00202 break;
00203 default:
00204 return (db_stat_usage());
00205 }
00206 break;
00207 case 's':
00208 if (ttype != T_NOTSET && ttype != T_DB)
00209 goto argcombo;
00210 ttype = T_DB;
00211 subdb = optarg;
00212 break;
00213 case 't':
00214 if (ttype != T_NOTSET) {
00215 argcombo: fprintf(stderr,
00216 "%s: illegal option combination\n",
00217 progname);
00218 return (EXIT_FAILURE);
00219 }
00220 ttype = T_TXN;
00221 break;
00222 case 'V':
00223 printf("%s\n", db_version(NULL, NULL, NULL));
00224 return (EXIT_SUCCESS);
00225 case 'X': case 'x':
00226 if (ttype != T_NOTSET && ttype != T_MUTEX)
00227 goto argcombo;
00228 ttype = T_MUTEX;
00229 if (ch != 'x')
00230 for (p = optarg; *p; ++p)
00231 switch (*p) {
00232 case 'A':
00233 LF_SET(DB_STAT_ALL);
00234 break;
00235 default:
00236 return (db_stat_usage());
00237 }
00238 break;
00239 case 'Z':
00240 LF_SET(DB_STAT_CLEAR);
00241 break;
00242 case '?':
00243 default:
00244 return (db_stat_usage());
00245 }
00246 argc -= optind;
00247 argv += optind;
00248
00249 switch (ttype) {
00250 case T_DB:
00251 if (db == NULL)
00252 return (db_stat_usage());
00253 break;
00254 case T_NOTSET:
00255 return (db_stat_usage());
00256
00257 case T_ENV:
00258 case T_LOCK:
00259 case T_LOG:
00260 case T_MPOOL:
00261 case T_REP:
00262 case T_TXN:
00263 case T_MUTEX:
00264 if (fast != 0)
00265 return (db_stat_usage());
00266 break;
00267 }
00268
00269
00270 __db_util_siginit();
00271
00272
00273
00274
00275
00276 retry: if ((ret = db_env_create(&dbenv, env_flags)) != 0) {
00277 fprintf(stderr,
00278 "%s: db_env_create: %s\n", progname, db_strerror(ret));
00279 goto err;
00280 }
00281
00282 dbenv->set_errfile(dbenv, stderr);
00283 dbenv->set_errpfx(dbenv, progname);
00284
00285 if (nflag) {
00286 if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
00287 dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
00288 goto err;
00289 }
00290 if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
00291 dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
00292 goto err;
00293 }
00294 }
00295
00296 if (passwd != NULL &&
00297 (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) {
00298 dbenv->err(dbenv, ret, "set_passwd");
00299 goto err;
00300 }
00301
00302
00303 if (db_stat_db_init(dbenv, home, ttype, cache, &private) != 0)
00304 goto err;
00305
00306 switch (ttype) {
00307 case T_DB:
00308 if (flags != 0)
00309 return (db_stat_usage());
00310
00311
00312 if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
00313 dbenv->err(dbenv, ret, "db_create");
00314 goto err;
00315 }
00316
00317 if ((ret = dbp->open(dbp,
00318 NULL, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
00319 dbenv->err(dbenv, ret, "DB->open: %s", db);
00320 goto err;
00321 }
00322
00323
00324 if (private) {
00325 if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0)
00326 goto err;
00327 if (resize) {
00328 (void)dbp->close(dbp, DB_NOSYNC);
00329 dbp = NULL;
00330
00331 (void)dbenv->close(dbenv, 0);
00332 dbenv = NULL;
00333 goto retry;
00334 }
00335 }
00336
00337
00338
00339
00340
00341
00342 if (subdb == NULL && dbp->type == DB_BTREE &&
00343 (ret = dbp->stat(dbp, NULL, &sp, DB_FAST_STAT)) != 0) {
00344 dbenv->err(dbenv, ret, "DB->stat");
00345 goto err;
00346 }
00347
00348 if (subdb != NULL ||
00349 dbp->type != DB_BTREE ||
00350 (sp->bt_metaflags & BTM_SUBDB) == 0) {
00351 if ((ret = db_create(&alt_dbp, dbenv, 0)) != 0) {
00352 dbenv->err(dbenv, ret, "db_create");
00353 goto err;
00354 }
00355 if ((ret = dbp->open(alt_dbp, NULL,
00356 db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
00357 if (subdb == NULL)
00358 dbenv->err(dbenv,
00359 ret, "DB->open: %s", db);
00360 else
00361 dbenv->err(dbenv,
00362 ret, "DB->open: %s:%s", db, subdb);
00363 (void)alt_dbp->close(alt_dbp, DB_NOSYNC);
00364 goto err;
00365 }
00366
00367 (void)dbp->close(dbp, DB_NOSYNC);
00368 dbp = alt_dbp;
00369 }
00370
00371 if (dbp->stat_print(dbp, flags))
00372 goto err;
00373 break;
00374 case T_ENV:
00375 if (dbenv->stat_print(dbenv, flags))
00376 goto err;
00377 break;
00378 case T_LOCK:
00379 if (dbenv->lock_stat_print(dbenv, flags))
00380 goto err;
00381 break;
00382 case T_LOG:
00383 if (dbenv->log_stat_print(dbenv, flags))
00384 goto err;
00385 break;
00386 case T_MPOOL:
00387 if (dbenv->memp_stat_print(dbenv, flags))
00388 goto err;
00389 break;
00390 case T_MUTEX:
00391 if (dbenv->mutex_stat_print(dbenv, flags))
00392 goto err;
00393 break;
00394 case T_REP:
00395 if (dbenv->rep_stat_print(dbenv, flags))
00396 goto err;
00397 break;
00398 case T_TXN:
00399 if (dbenv->txn_stat_print(dbenv, flags))
00400 goto err;
00401 break;
00402 case T_NOTSET:
00403 dbenv->errx(dbenv, "Unknown statistics flag");
00404 goto err;
00405 }
00406
00407 if (0) {
00408 err: exitval = 1;
00409 }
00410 if (dbp != NULL && (ret = dbp->close(dbp, DB_NOSYNC)) != 0) {
00411 exitval = 1;
00412 dbenv->err(dbenv, ret, "close");
00413 }
00414 if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
00415 exitval = 1;
00416 fprintf(stderr,
00417 "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00418 }
00419
00420 if (passwd != NULL)
00421 free(passwd);
00422
00423
00424 __db_util_sigresend();
00425
00426 return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00427 }
00428
00429
00430
00431
00432
00433 int
00434 db_stat_db_init(dbenv, home, ttype, cache, is_private)
00435 DB_ENV *dbenv;
00436 char *home;
00437 test_t ttype;
00438 u_int32_t cache;
00439 int *is_private;
00440 {
00441 u_int32_t oflags;
00442 int ret;
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 *is_private = 0;
00455 if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) == 0)
00456 return (0);
00457 if (ret == DB_VERSION_MISMATCH)
00458 goto err;
00459 if (ttype != T_DB && ttype != T_LOG) {
00460 dbenv->err(dbenv, ret, "DB_ENV->open%s%s",
00461 home == NULL ? "" : ": ", home == NULL ? "" : home);
00462 return (1);
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
00476 dbenv->err(dbenv, ret, "set_cachesize");
00477 return (1);
00478 }
00479 *is_private = 1;
00480 oflags = DB_CREATE | DB_PRIVATE | DB_USE_ENVIRON;
00481 if (ttype == T_DB)
00482 oflags |= DB_INIT_MPOOL;
00483 if (ttype == T_LOG)
00484 oflags |= DB_INIT_LOG;
00485 if (ttype == T_REP)
00486 oflags |= DB_INIT_REP;
00487 if ((ret = dbenv->open(dbenv, home, oflags, 0)) == 0)
00488 return (0);
00489
00490
00491 err: dbenv->err(dbenv, ret, "DB_ENV->open");
00492 return (1);
00493 }
00494
00495 int
00496 db_stat_usage()
00497 {
00498 fprintf(stderr, "usage: %s %s\n", progname,
00499 "-d file [-fN] [-h home] [-P password] [-s database]");
00500 fprintf(stderr, "usage: %s %s\n\t%s\n", progname,
00501 "[-cEelmNrtVxZ] [-C Aclop]",
00502 "[-h home] [-L A] [-M A] [-P password] [-R A] [-X A]");
00503 return (EXIT_FAILURE);
00504 }
00505
00506 int
00507 db_stat_version_check()
00508 {
00509 int v_major, v_minor, v_patch;
00510
00511
00512 (void)db_version(&v_major, &v_minor, &v_patch);
00513 if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
00514 fprintf(stderr,
00515 "%s: version %d.%d doesn't match library version %d.%d\n",
00516 progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
00517 v_major, v_minor);
00518 return (EXIT_FAILURE);
00519 }
00520 return (0);
00521 }