Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

db_stat.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_stat.c,v 12.6 2005/10/05 22:27:27 ubell Exp $
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_init __P((DB_ENV *, char *, test_t, u_int32_t, int *));
00044 int      main __P((int, char *[]));
00045 int      usage __P((void));
00046 int      version_check __P((void));
00047 
00048 const char *progname;
00049 
00050 int
00051 main(argc, argv)
00052         int argc;
00053         char *argv[];
00054 {
00055         extern char *optarg;
00056         extern int optind;
00057         DB_ENV  *dbenv;
00058         DB_BTREE_STAT *sp;
00059         DB *alt_dbp, *dbp;
00060         test_t ttype;
00061         u_int32_t cache, env_flags, fast, flags;
00062         int ch, exitval;
00063         int nflag, private, resize, ret;
00064         char *db, *home, *p, *passwd, *subdb;
00065 
00066         if ((progname = strrchr(argv[0], '/')) == NULL)
00067                 progname = argv[0];
00068         else
00069                 ++progname;
00070 
00071         if ((ret = version_check()) != 0)
00072                 return (ret);
00073 
00074         dbenv = NULL;
00075         dbp = NULL;
00076         ttype = T_NOTSET;
00077         cache = MEGABYTE;
00078         exitval = fast = flags = nflag = private = 0;
00079         db = home = passwd = subdb = NULL;
00080         env_flags = 0;
00081 
00082         while ((ch = getopt(argc,
00083             argv, "C:cd:Eefh:L:lM:mNP:R:rs:tVxX:Z")) != EOF)
00084                 switch (ch) {
00085                 case 'C': case 'c':
00086                         if (ttype != T_NOTSET && ttype != T_LOCK)
00087                                 goto argcombo;
00088                         ttype = T_LOCK;
00089                         if (ch != 'c')
00090                                 for (p = optarg; *p; ++p)
00091                                         switch (*p) {
00092                                         case 'A':
00093                                                 LF_SET(DB_STAT_ALL);
00094                                                 break;
00095                                         case 'c':
00096                                                 LF_SET(DB_STAT_LOCK_CONF);
00097                                                 break;
00098                                         case 'l':
00099                                                 LF_SET(DB_STAT_LOCK_LOCKERS);
00100                                                 break;
00101                                         case 'm': /* Backward compatible. */
00102                                                 break;
00103                                         case 'o':
00104                                                 LF_SET(DB_STAT_LOCK_OBJECTS);
00105                                                 break;
00106                                         case 'p':
00107                                                 LF_SET(DB_STAT_LOCK_PARAMS);
00108                                                 break;
00109                                         default:
00110                                                 return (usage());
00111                                         }
00112                         break;
00113                 case 'd':
00114                         if (ttype != T_NOTSET && ttype != T_DB)
00115                                 goto argcombo;
00116                         ttype = T_DB;
00117                         db = optarg;
00118                         break;
00119                 case 'E': case 'e':
00120                         if (ttype != T_NOTSET && ttype != T_ENV)
00121                                 goto argcombo;
00122                         ttype = T_ENV;
00123                         LF_SET(DB_STAT_SUBSYSTEM);
00124                         if (ch == 'E')
00125                                 LF_SET(DB_STAT_ALL);
00126                         break;
00127                 case 'f':
00128                         fast = DB_FAST_STAT;
00129                         break;
00130                 case 'h':
00131                         home = optarg;
00132                         break;
00133                 case 'L': case 'l':
00134                         if (ttype != T_NOTSET && ttype != T_LOG)
00135                                 goto argcombo;
00136                         ttype = T_LOG;
00137                         if (ch != 'l')
00138                                 for (p = optarg; *p; ++p)
00139                                         switch (*p) {
00140                                         case 'A':
00141                                                 LF_SET(DB_STAT_ALL);
00142                                                 break;
00143                                         default:
00144                                                 return (usage());
00145                                         }
00146                         break;
00147                 case 'M': case 'm':
00148                         if (ttype != T_NOTSET && ttype != T_MPOOL)
00149                                 goto argcombo;
00150                         ttype = T_MPOOL;
00151                         if (ch != 'm')
00152                                 for (p = optarg; *p; ++p)
00153                                         switch (*p) {
00154                                         case 'A':
00155                                                 LF_SET(DB_STAT_ALL);
00156                                                 break;
00157                                         case 'h':
00158                                                 LF_SET(DB_STAT_MEMP_HASH);
00159                                                 break;
00160                                         case 'm': /* Backward compatible. */
00161                                                 break;
00162                                         default:
00163                                                 return (usage());
00164                                         }
00165                         break;
00166                 case 'N':
00167                         nflag = 1;
00168                         break;
00169                 case 'P':
00170                         passwd = strdup(optarg);
00171                         memset(optarg, 0, strlen(optarg));
00172                         if (passwd == NULL) {
00173                                 fprintf(stderr, "%s: strdup: %s\n",
00174                                     progname, strerror(errno));
00175                                 return (EXIT_FAILURE);
00176                         }
00177                         break;
00178                 case 'R': case 'r':
00179                         if (ttype != T_NOTSET && ttype != T_REP)
00180                                 goto argcombo;
00181                         ttype = T_REP;
00182                         if (ch != 'r')
00183                                 for (p = optarg; *p; ++p)
00184                                         switch (*p) {
00185                                         case 'A':
00186                                                 LF_SET(DB_STAT_ALL);
00187                                                 break;
00188                                         default:
00189                                                 return (usage());
00190                                         }
00191                         break;
00192                 case 's':
00193                         if (ttype != T_NOTSET && ttype != T_DB)
00194                                 goto argcombo;
00195                         ttype = T_DB;
00196                         subdb = optarg;
00197                         break;
00198                 case 't':
00199                         if (ttype != T_NOTSET) {
00200 argcombo:                       fprintf(stderr,
00201                                     "%s: illegal option combination\n",
00202                                     progname);
00203                                 return (EXIT_FAILURE);
00204                         }
00205                         ttype = T_TXN;
00206                         break;
00207                 case 'V':
00208                         printf("%s\n", db_version(NULL, NULL, NULL));
00209                         return (EXIT_SUCCESS);
00210                 case 'X': case 'x':
00211                         if (ttype != T_NOTSET && ttype != T_MUTEX)
00212                                 goto argcombo;
00213                         ttype = T_MUTEX;
00214                         if (ch != 'x')
00215                                 for (p = optarg; *p; ++p)
00216                                         switch (*p) {
00217                                                 case 'A':
00218                                                         LF_SET(DB_STAT_ALL);
00219                                                         break;
00220                                                 default:
00221                                                         return (usage());
00222                                         }
00223                         break;
00224                 case 'Z':
00225                         LF_SET(DB_STAT_CLEAR);
00226                         break;
00227                 case '?':
00228                 default:
00229                         return (usage());
00230                 }
00231         argc -= optind;
00232         argv += optind;
00233 
00234         switch (ttype) {
00235         case T_DB:
00236                 if (db == NULL)
00237                         return (usage());
00238                 break;
00239         case T_NOTSET:
00240                 return (usage());
00241                 /* NOTREACHED */
00242         case T_ENV:
00243         case T_LOCK:
00244         case T_LOG:
00245         case T_MPOOL:
00246         case T_REP:
00247         case T_TXN:
00248         case T_MUTEX:
00249                 if (fast != 0)
00250                         return (usage());
00251                 break;
00252         }
00253 
00254         /* Handle possible interruptions. */
00255         __db_util_siginit();
00256 
00257         /*
00258          * Create an environment object and initialize it for error
00259          * reporting.
00260          */
00261 retry:  if ((ret = db_env_create(&dbenv, env_flags)) != 0) {
00262                 fprintf(stderr,
00263                     "%s: db_env_create: %s\n", progname, db_strerror(ret));
00264                 goto err;
00265         }
00266 
00267         dbenv->set_errfile(dbenv, stderr);
00268         dbenv->set_errpfx(dbenv, progname);
00269 
00270         if (nflag) {
00271                 if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
00272                         dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
00273                         goto err;
00274                 }
00275                 if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
00276                         dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
00277                         goto err;
00278                 }
00279         }
00280 
00281         if (passwd != NULL &&
00282             (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) {
00283                 dbenv->err(dbenv, ret, "set_passwd");
00284                 goto err;
00285         }
00286 
00287         /* Initialize the environment. */
00288         if (db_init(dbenv, home, ttype, cache, &private) != 0)
00289                 goto err;
00290 
00291         switch (ttype) {
00292         case T_DB:
00293                 if (flags != 0)
00294                         return (usage());
00295 
00296                 /* Create the DB object and open the file. */
00297                 if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
00298                         dbenv->err(dbenv, ret, "db_create");
00299                         goto err;
00300                 }
00301 
00302                 if ((ret = dbp->open(dbp,
00303                     NULL, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
00304                         dbenv->err(dbenv, ret, "DB->open: %s", db);
00305                         goto err;
00306                 }
00307 
00308                 /* Check if cache is too small for this DB's pagesize. */
00309                 if (private) {
00310                         if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0)
00311                                 goto err;
00312                         if (resize) {
00313                                 (void)dbp->close(dbp, DB_NOSYNC);
00314                                 dbp = NULL;
00315 
00316                                 (void)dbenv->close(dbenv, 0);
00317                                 dbenv = NULL;
00318                                 goto retry;
00319                         }
00320                 }
00321 
00322                 /*
00323                  * See if we can open this db read/write to update counts.
00324                  * If its a master-db then we cannot.  So check to see,
00325                  * if its btree then it might be.
00326                  */
00327                 if (subdb == NULL && dbp->type == DB_BTREE &&
00328                     (ret = dbp->stat(dbp, NULL, &sp, DB_FAST_STAT)) != 0) {
00329                         dbenv->err(dbenv, ret, "DB->stat");
00330                         goto err;
00331                 }
00332 
00333                 if (subdb != NULL ||
00334                     dbp->type != DB_BTREE ||
00335                     (sp->bt_metaflags & BTM_SUBDB) == 0) {
00336                         if ((ret = db_create(&alt_dbp, dbenv, 0)) != 0) {
00337                                 dbenv->err(dbenv, ret, "db_create");
00338                                 goto err;
00339                         }
00340                         if ((ret = dbp->open(alt_dbp, NULL,
00341                             db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
00342                                 if (subdb == NULL)
00343                                         dbenv->err(dbenv,
00344                                            ret, "DB->open: %s", db);
00345                                 else
00346                                         dbenv->err(dbenv,
00347                                            ret, "DB->open: %s:%s", db, subdb);
00348                                 (void)alt_dbp->close(alt_dbp, DB_NOSYNC);
00349                                 goto err;
00350                         }
00351 
00352                         (void)dbp->close(dbp, DB_NOSYNC);
00353                         dbp = alt_dbp;
00354                 }
00355 
00356                 if (dbp->stat_print(dbp, flags))
00357                         goto err;
00358                 break;
00359         case T_ENV:
00360                 if (dbenv->stat_print(dbenv, flags))
00361                         goto err;
00362                 break;
00363         case T_LOCK:
00364                 if (dbenv->lock_stat_print(dbenv, flags))
00365                         goto err;
00366                 break;
00367         case T_LOG:
00368                 if (dbenv->log_stat_print(dbenv, flags))
00369                         goto err;
00370                 break;
00371         case T_MPOOL:
00372                 if (dbenv->memp_stat_print(dbenv, flags))
00373                         goto err;
00374                 break;
00375         case T_MUTEX:
00376                 if (dbenv->mutex_stat_print(dbenv, flags))
00377                         goto err;
00378                 break;
00379         case T_REP:
00380                 if (dbenv->rep_stat_print(dbenv, flags))
00381                         goto err;
00382                 break;
00383         case T_TXN:
00384                 if (dbenv->txn_stat_print(dbenv, flags))
00385                         goto err;
00386                 break;
00387         case T_NOTSET:
00388                 dbenv->errx(dbenv, "Unknown statistics flag");
00389                 goto err;
00390         }
00391 
00392         if (0) {
00393 err:            exitval = 1;
00394         }
00395         if (dbp != NULL && (ret = dbp->close(dbp, DB_NOSYNC)) != 0) {
00396                 exitval = 1;
00397                 dbenv->err(dbenv, ret, "close");
00398         }
00399         if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
00400                 exitval = 1;
00401                 fprintf(stderr,
00402                     "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00403         }
00404 
00405         if (passwd != NULL)
00406                 free(passwd);
00407 
00408         /* Resend any caught signal. */
00409         __db_util_sigresend();
00410 
00411         return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00412 }
00413 
00414 /*
00415  * db_init --
00416  *      Initialize the environment.
00417  */
00418 int
00419 db_init(dbenv, home, ttype, cache, is_private)
00420         DB_ENV *dbenv;
00421         char *home;
00422         test_t ttype;
00423         u_int32_t cache;
00424         int *is_private;
00425 {
00426         u_int32_t oflags;
00427         int ret;
00428 
00429         /*
00430          * If our environment open fails, and we're trying to look at a
00431          * shared region, it's a hard failure.
00432          *
00433          * We will probably just drop core if the environment we join does
00434          * not include a memory pool.  This is probably acceptable; trying
00435          * to use an existing environment that does not contain a memory
00436          * pool to look at a database can be safely construed as operator
00437          * error, I think.
00438          */
00439         *is_private = 0;
00440         if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) == 0)
00441                 return (0);
00442         if (ret == DB_VERSION_MISMATCH)
00443                 goto err;
00444         if (ttype != T_DB && ttype != T_LOG) {
00445                 dbenv->err(dbenv, ret, "DB_ENV->open%s%s",
00446                     home == NULL ? "" : ": ", home == NULL ? "" : home);
00447                 return (1);
00448         }
00449 
00450         /*
00451          * We're looking at a database or set of log files and no environment
00452          * exists.  Create one, but make it private so no files are actually
00453          * created.  Declare a reasonably large cache so that we don't fail
00454          * when reporting statistics on large databases.
00455          *
00456          * An environment is required to look at databases because we may be
00457          * trying to look at databases in directories other than the current
00458          * one.
00459          */
00460         if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
00461                 dbenv->err(dbenv, ret, "set_cachesize");
00462                 return (1);
00463         }
00464         *is_private = 1;
00465         oflags = DB_CREATE | DB_PRIVATE | DB_USE_ENVIRON;
00466         if (ttype == T_DB)
00467                 oflags |= DB_INIT_MPOOL;
00468         if (ttype == T_LOG)
00469                 oflags |= DB_INIT_LOG;
00470         if (ttype == T_REP)
00471                 oflags |= DB_INIT_REP;
00472         if ((ret = dbenv->open(dbenv, home, oflags, 0)) == 0)
00473                 return (0);
00474 
00475         /* An environment is required. */
00476 err:    dbenv->err(dbenv, ret, "DB_ENV->open");
00477         return (1);
00478 }
00479 
00480 int
00481 usage()
00482 {
00483         fprintf(stderr, "usage: %s %s\n", progname,
00484             "-d file [-fN] [-h home] [-P password] [-s database]");
00485         fprintf(stderr, "usage: %s %s\n\t%s\n", progname,
00486             "[-cEelmNrtVxZ] [-C Aclop]",
00487             "[-h home] [-L A] [-M A] [-P password] [-R A] [-X A]");
00488         return (EXIT_FAILURE);
00489 }
00490 
00491 int
00492 version_check()
00493 {
00494         int v_major, v_minor, v_patch;
00495 
00496         /* Make sure we're loaded with the right version of the DB library. */
00497         (void)db_version(&v_major, &v_minor, &v_patch);
00498         if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
00499                 fprintf(stderr,
00500         "%s: version %d.%d doesn't match library version %d.%d\n",
00501                     progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
00502                     v_major, v_minor);
00503                 return (EXIT_FAILURE);
00504         }
00505         return (0);
00506 }

Generated on Sun Dec 25 12:14:17 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2