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_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': /* Backward compatible. */
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': /* Backward compatible. */
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                 /* NOTREACHED */
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         /* Handle possible interruptions. */
00270         __db_util_siginit();
00271 
00272         /*
00273          * Create an environment object and initialize it for error
00274          * reporting.
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         /* Initialize the environment. */
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                 /* Create the DB object and open the file. */
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                 /* Check if cache is too small for this DB's pagesize. */
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                  * See if we can open this db read/write to update counts.
00339                  * If its a master-db then we cannot.  So check to see,
00340                  * if its btree then it might be.
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         /* Resend any caught signal. */
00424         __db_util_sigresend();
00425 
00426         return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00427 }
00428 
00429 /*
00430  * db_init --
00431  *      Initialize the environment.
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          * If our environment open fails, and we're trying to look at a
00446          * shared region, it's a hard failure.
00447          *
00448          * We will probably just drop core if the environment we join does
00449          * not include a memory pool.  This is probably acceptable; trying
00450          * to use an existing environment that does not contain a memory
00451          * pool to look at a database can be safely construed as operator
00452          * error, I think.
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          * We're looking at a database or set of log files and no environment
00467          * exists.  Create one, but make it private so no files are actually
00468          * created.  Declare a reasonably large cache so that we don't fail
00469          * when reporting statistics on large databases.
00470          *
00471          * An environment is required to look at databases because we may be
00472          * trying to look at databases in directories other than the current
00473          * one.
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         /* An environment is required. */
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         /* Make sure we're loaded with the right version of the DB library. */
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 }

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