1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996,2008 Oracle. All rights reserved. 5 * 6 * $Id: env_stat.c,v 12.64 2008/03/12 20:52:53 mbrey Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#include "dbinc/db_page.h" 13#include "dbinc/db_am.h" 14#include "dbinc/lock.h" 15#include "dbinc/log.h" 16#include "dbinc/mp.h" 17#include "dbinc/txn.h" 18 19#ifdef HAVE_STATISTICS 20static int __env_print_all __P((ENV *, u_int32_t)); 21static int __env_print_dbenv_all __P((ENV *, u_int32_t)); 22static int __env_print_env_all __P((ENV *, u_int32_t)); 23static int __env_print_fh __P((ENV *)); 24static int __env_print_stats __P((ENV *, u_int32_t)); 25static int __env_print_thread __P((ENV *)); 26static int __env_stat_print __P((ENV *, u_int32_t)); 27static char *__env_thread_state_print __P((DB_THREAD_STATE)); 28static const char * 29 __reg_type __P((reg_type_t)); 30 31/* 32 * __env_stat_print_pp -- 33 * ENV->stat_print pre/post processor. 34 * 35 * PUBLIC: int __env_stat_print_pp __P((DB_ENV *, u_int32_t)); 36 */ 37int 38__env_stat_print_pp(dbenv, flags) 39 DB_ENV *dbenv; 40 u_int32_t flags; 41{ 42 DB_THREAD_INFO *ip; 43 ENV *env; 44 int ret; 45 46 env = dbenv->env; 47 48 ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->stat_print"); 49 50 if ((ret = __db_fchk(env, "DB_ENV->stat_print", 51 flags, DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_SUBSYSTEM)) != 0) 52 return (ret); 53 54 ENV_ENTER(env, ip); 55 REPLICATION_WRAP(env, (__env_stat_print(env, flags)), 0, ret); 56 ENV_LEAVE(env, ip); 57 return (ret); 58} 59 60/* 61 * __env_stat_print -- 62 * ENV->stat_print method. 63 */ 64static int 65__env_stat_print(env, flags) 66 ENV *env; 67 u_int32_t flags; 68{ 69 time_t now; 70 int ret; 71 char time_buf[CTIME_BUFLEN]; 72 73 (void)time(&now); 74 __db_msg(env, "%.24s\tLocal time", __os_ctime(&now, time_buf)); 75 76 if ((ret = __env_print_stats(env, flags)) != 0) 77 return (ret); 78 79 if (LF_ISSET(DB_STAT_ALL) && 80 (ret = __env_print_all(env, flags)) != 0) 81 return (ret); 82 83 if ((ret = __env_print_thread(env)) != 0) 84 return (ret); 85 86 if ((ret = __env_print_fh(env)) != 0) 87 return (ret); 88 89 if (!LF_ISSET(DB_STAT_SUBSYSTEM)) 90 return (0); 91 92 if (LOGGING_ON(env)) { 93 __db_msg(env, "%s", DB_GLOBAL(db_line)); 94 if ((ret = __log_stat_print(env, flags)) != 0) 95 return (ret); 96 97 __db_msg(env, "%s", DB_GLOBAL(db_line)); 98 if ((ret = __dbreg_stat_print(env, flags)) != 0) 99 return (ret); 100 } 101 102 if (LOCKING_ON(env)) { 103 __db_msg(env, "%s", DB_GLOBAL(db_line)); 104 if ((ret = __lock_stat_print(env, flags)) != 0) 105 return (ret); 106 } 107 108 if (MPOOL_ON(env)) { 109 __db_msg(env, "%s", DB_GLOBAL(db_line)); 110 if ((ret = __memp_stat_print(env, flags)) != 0) 111 return (ret); 112 } 113 114 if (REP_ON(env)) { 115 __db_msg(env, "%s", DB_GLOBAL(db_line)); 116 if ((ret = __rep_stat_print(env, flags)) != 0) 117 return (ret); 118 } 119 120 if (TXN_ON(env)) { 121 __db_msg(env, "%s", DB_GLOBAL(db_line)); 122 if ((ret = __txn_stat_print(env, flags)) != 0) 123 return (ret); 124 } 125 126#ifdef HAVE_MUTEX_SUPPORT 127 /* 128 * Dump the mutexes last. If DB_STAT_CLEAR is set this will 129 * clear out the mutex counters and we want to see them in 130 * the context of the other subsystems first. 131 */ 132 if (MUTEX_ON(env)) { 133 __db_msg(env, "%s", DB_GLOBAL(db_line)); 134 if ((ret = __mutex_stat_print(env, flags)) != 0) 135 return (ret); 136 } 137#endif 138 139 return (0); 140} 141 142/* 143 * __env_print_stats -- 144 * Display the default environment statistics. 145 * 146 */ 147static int 148__env_print_stats(env, flags) 149 ENV *env; 150 u_int32_t flags; 151{ 152 REGENV *renv; 153 REGINFO *infop; 154 char time_buf[CTIME_BUFLEN]; 155 156 infop = env->reginfo; 157 renv = infop->primary; 158 159 if (LF_ISSET(DB_STAT_ALL)) { 160 __db_msg(env, "%s", DB_GLOBAL(db_line)); 161 __db_msg(env, "Default database environment information:"); 162 } 163 STAT_HEX("Magic number", renv->magic); 164 STAT_LONG("Panic value", renv->panic); 165 __db_msg(env, "%d.%d.%d\tEnvironment version", 166 renv->majver, renv->minver, renv->patchver); 167 STAT_LONG("Btree version", DB_BTREEVERSION); 168 STAT_LONG("Hash version", DB_HASHVERSION); 169 STAT_LONG("Lock version", DB_LOCKVERSION); 170 STAT_LONG("Log version", DB_LOGVERSION); 171 STAT_LONG("Queue version", DB_QAMVERSION); 172 STAT_LONG("Sequence version", DB_SEQUENCE_VERSION); 173 STAT_LONG("Txn version", DB_TXNVERSION); 174 __db_msg(env, 175 "%.24s\tCreation time", __os_ctime(&renv->timestamp, time_buf)); 176 STAT_HEX("Environment ID", renv->envid); 177 __mutex_print_debug_single(env, 178 "Primary region allocation and reference count mutex", 179 renv->mtx_regenv, flags); 180 STAT_LONG("References", renv->refcnt); 181 182 return (0); 183} 184 185/* 186 * __env_print_all -- 187 * Display the debugging environment statistics. 188 */ 189static int 190__env_print_all(env, flags) 191 ENV *env; 192 u_int32_t flags; 193{ 194 int ret, t_ret; 195 196 /* 197 * There are two structures -- DB_ENV and ENV. 198 */ 199 ret = __env_print_dbenv_all(env, flags); 200 if ((t_ret = __env_print_env_all(env, flags)) != 0 && ret == 0) 201 ret = t_ret; 202 203 return (ret); 204} 205 206/* 207 * __env_print_dbenv_all -- 208 * Display the debugging environment statistics. 209 */ 210static int 211__env_print_dbenv_all(env, flags) 212 ENV *env; 213 u_int32_t flags; 214{ 215 static const FN db_env_fn[] = { 216 { DB_ENV_AUTO_COMMIT, "DB_ENV_AUTO_COMMIT" }, 217 { DB_ENV_CDB_ALLDB, "DB_ENV_CDB_ALLDB" }, 218 { DB_ENV_DIRECT_DB, "DB_ENV_DIRECT_DB" }, 219 { DB_ENV_DSYNC_DB, "DB_ENV_DSYNC_DB" }, 220 { DB_ENV_MULTIVERSION, "DB_ENV_MULTIVERSION" }, 221 { DB_ENV_NOLOCKING, "DB_ENV_NOLOCKING" }, 222 { DB_ENV_NOMMAP, "DB_ENV_NOMMAP" }, 223 { DB_ENV_NOPANIC, "DB_ENV_NOPANIC" }, 224 { DB_ENV_OVERWRITE, "DB_ENV_OVERWRITE" }, 225 { DB_ENV_REGION_INIT, "DB_ENV_REGION_INIT" }, 226 { DB_ENV_RPCCLIENT, "DB_ENV_RPCCLIENT" }, 227 { DB_ENV_RPCCLIENT_GIVEN, "DB_ENV_RPCCLIENT_GIVEN" }, 228 { DB_ENV_TIME_NOTGRANTED, "DB_ENV_TIME_NOTGRANTED" }, 229 { DB_ENV_TXN_NOSYNC, "DB_ENV_TXN_NOSYNC" }, 230 { DB_ENV_TXN_NOWAIT, "DB_ENV_TXN_NOWAIT" }, 231 { DB_ENV_TXN_SNAPSHOT, "DB_ENV_TXN_SNAPSHOT" }, 232 { DB_ENV_TXN_WRITE_NOSYNC, "DB_ENV_TXN_WRITE_NOSYNC" }, 233 { DB_ENV_YIELDCPU, "DB_ENV_YIELDCPU" }, 234 { 0, NULL } 235 }; 236 static const FN vfn[] = { 237 { DB_VERB_DEADLOCK, "DB_VERB_DEADLOCK" }, 238 { DB_VERB_FILEOPS, "DB_VERB_FILEOPS" }, 239 { DB_VERB_FILEOPS_ALL, "DB_VERB_FILEOPS_ALL" }, 240 { DB_VERB_RECOVERY, "DB_VERB_RECOVERY" }, 241 { DB_VERB_REGISTER, "DB_VERB_REGISTER" }, 242 { DB_VERB_REPLICATION, "DB_VERB_REPLICATION" }, 243 { DB_VERB_REP_ELECT, "DB_VERB_REP_ELECT" }, 244 { DB_VERB_REP_LEASE, "DB_VERB_REP_LEASE" }, 245 { DB_VERB_REP_MISC, "DB_VERB_REP_MISC" }, 246 { DB_VERB_REP_MSGS, "DB_VERB_REP_MSGS" }, 247 { DB_VERB_REP_SYNC, "DB_VERB_REP_SYNC" }, 248 { DB_VERB_REPMGR_CONNFAIL, "DB_VERB_REPMGR_CONNFAIL" }, 249 { DB_VERB_REPMGR_MISC, "DB_VERB_REPMGR_MISC" }, 250 { DB_VERB_WAITSFOR, "DB_VERB_WAITSFOR" }, 251 { 0, NULL } 252 }; 253 DB_ENV *dbenv; 254 DB_MSGBUF mb; 255 char **p; 256 257 dbenv = env->dbenv; 258 DB_MSGBUF_INIT(&mb); 259 260 __db_msg(env, "%s", DB_GLOBAL(db_line)); 261 STAT_POINTER("ENV", dbenv->env); 262 __mutex_print_debug_single( 263 env, "DB_ENV handle mutex", dbenv->mtx_db_env, flags); 264 STAT_ISSET("Errcall", dbenv->db_errcall); 265 STAT_ISSET("Errfile", dbenv->db_errfile); 266 STAT_STRING("Errpfx", dbenv->db_errpfx); 267 STAT_ISSET("Msgfile", dbenv->db_msgfile); 268 STAT_ISSET("Msgcall", dbenv->db_msgcall); 269 270 STAT_ISSET("AppDispatch", dbenv->app_dispatch); 271 STAT_ISSET("Event", dbenv->db_event_func); 272 STAT_ISSET("Feedback", dbenv->db_feedback); 273 STAT_ISSET("Free", dbenv->db_free); 274 STAT_ISSET("Panic", dbenv->db_paniccall); 275 STAT_ISSET("Malloc", dbenv->db_malloc); 276 STAT_ISSET("Realloc", dbenv->db_realloc); 277 STAT_ISSET("IsAlive", dbenv->is_alive); 278 STAT_ISSET("ThreadId", dbenv->thread_id); 279 STAT_ISSET("ThreadIdString", dbenv->thread_id_string); 280 281 STAT_STRING("Log dir", dbenv->db_log_dir); 282 STAT_STRING("Tmp dir", dbenv->db_tmp_dir); 283 if (dbenv->db_data_dir == NULL) 284 STAT_ISSET("Data dir", dbenv->db_data_dir); 285 else { 286 for (p = dbenv->db_data_dir; *p != NULL; ++p) 287 __db_msgadd(env, &mb, "%s\tData dir", *p); 288 DB_MSGBUF_FLUSH(env, &mb); 289 } 290 291 STAT_STRING( 292 "Intermediate directory mode", dbenv->intermediate_dir_mode); 293 294 STAT_LONG("Shared memory key", dbenv->shm_key); 295 296 STAT_ISSET("Password", dbenv->passwd); 297 298 STAT_ISSET("RPC client", dbenv->cl_handle); 299 STAT_ULONG("RPC client ID", dbenv->cl_id); 300 301 STAT_ISSET("App private", dbenv->app_private); 302 STAT_ISSET("Api1 internal", dbenv->api1_internal); 303 STAT_ISSET("Api2 internal", dbenv->api2_internal); 304 305 __db_prflags(env, NULL, dbenv->verbose, vfn, NULL, "\tVerbose flags"); 306 307 STAT_ULONG("Mutex align", dbenv->mutex_align); 308 STAT_ULONG("Mutex cnt", dbenv->mutex_cnt); 309 STAT_ULONG("Mutex inc", dbenv->mutex_inc); 310 STAT_ULONG("Mutex tas spins", dbenv->mutex_tas_spins); 311 312 STAT_ISSET("Lock conflicts", dbenv->lk_conflicts); 313 STAT_LONG("Lock modes", dbenv->lk_modes); 314 STAT_ULONG("Lock detect", dbenv->lk_detect); 315 STAT_ULONG("Lock max", dbenv->lk_max); 316 STAT_ULONG("Lock max lockers", dbenv->lk_max_lockers); 317 STAT_ULONG("Lock max objects", dbenv->lk_max_objects); 318 STAT_ULONG("Lock partitions", dbenv->lk_partitions); 319 STAT_ULONG("Lock timeout", dbenv->lk_timeout); 320 321 STAT_ULONG("Log bsize", dbenv->lg_bsize); 322 STAT_FMT("Log file mode", "%#o", int, dbenv->lg_filemode); 323 STAT_ULONG("Log region max", dbenv->lg_regionmax); 324 STAT_ULONG("Log size", dbenv->lg_size); 325 326 STAT_ULONG("Cache GB", dbenv->mp_gbytes); 327 STAT_ULONG("Cache B", dbenv->mp_bytes); 328 STAT_ULONG("Cache max GB", dbenv->mp_max_gbytes); 329 STAT_ULONG("Cache max B", dbenv->mp_max_bytes); 330 STAT_ULONG("Cache mmap size", dbenv->mp_mmapsize); 331 STAT_ULONG("Cache max open fd", dbenv->mp_maxopenfd); 332 STAT_ULONG("Cache max write", dbenv->mp_maxwrite); 333 STAT_ULONG("Cache number", dbenv->mp_ncache); 334 STAT_ULONG("Cache max write sleep", dbenv->mp_maxwrite_sleep); 335 336 STAT_ULONG("Txn max", dbenv->tx_max); 337 STAT_ULONG("Txn timestamp", dbenv->tx_timestamp); 338 STAT_ULONG("Txn timeout", dbenv->tx_timeout); 339 340 STAT_ULONG("Thread count", dbenv->thr_max); 341 342 STAT_ISSET("Registry", dbenv->registry); 343 STAT_ULONG("Registry offset", dbenv->registry_off); 344 345 __db_prflags(env, 346 NULL, dbenv->flags, db_env_fn, NULL, "\tPublic environment flags"); 347 348 return (0); 349} 350 351/* 352 * __env_print_env_all -- 353 * Display the debugging environment statistics. 354 */ 355static int 356__env_print_env_all(env, flags) 357 ENV *env; 358 u_int32_t flags; 359{ 360 static const FN env_fn[] = { 361 { ENV_CDB, "ENV_CDB" }, 362 { ENV_DBLOCAL, "ENV_DBLOCAL" }, 363 { ENV_LOCKDOWN, "ENV_LOCKDOWN" }, 364 { ENV_NO_OUTPUT_SET, "ENV_NO_OUTPUT_SET" }, 365 { ENV_OPEN_CALLED, "ENV_OPEN_CALLED" }, 366 { ENV_PRIVATE, "ENV_PRIVATE" }, 367 { ENV_RECOVER_FATAL, "ENV_RECOVER_FATAL" }, 368 { ENV_REF_COUNTED, "ENV_REF_COUNTED" }, 369 { ENV_SYSTEM_MEM, "ENV_SYSTEM_MEM" }, 370 { ENV_THREAD, "ENV_THREAD" }, 371 { 0, NULL } 372 }; 373 static const FN ofn[] = { 374 { DB_CREATE, "DB_CREATE" }, 375 { DB_FORCE, "DB_FORCE" }, 376 { DB_INIT_CDB, "DB_INIT_CDB" }, 377 { DB_INIT_LOCK, "DB_INIT_LOCK" }, 378 { DB_INIT_LOG, "DB_INIT_LOG" }, 379 { DB_INIT_MPOOL, "DB_INIT_MPOOL" }, 380 { DB_INIT_REP, "DB_INIT_REP" }, 381 { DB_INIT_TXN, "DB_INIT_TXN" }, 382 { DB_LOCKDOWN, "DB_LOCKDOWN" }, 383 { DB_NOMMAP, "DB_NOMMAP" }, 384 { DB_PRIVATE, "DB_PRIVATE" }, 385 { DB_RDONLY, "DB_RDONLY" }, 386 { DB_RECOVER, "DB_RECOVER" }, 387 { DB_RECOVER_FATAL, "DB_RECOVER_FATAL" }, 388 { DB_SYSTEM_MEM, "DB_SYSTEM_MEM" }, 389 { DB_THREAD, "DB_THREAD" }, 390 { DB_TRUNCATE, "DB_TRUNCATE" }, 391 { DB_TXN_NOSYNC, "DB_TXN_NOSYNC" }, 392 { DB_USE_ENVIRON, "DB_USE_ENVIRON" }, 393 { DB_USE_ENVIRON_ROOT, "DB_USE_ENVIRON_ROOT" }, 394 { 0, NULL } 395 }; 396 static const FN regenvfn[] = { 397 { DB_REGENV_REPLOCKED, "DB_REGENV_REPLOCKED" }, 398 { 0, NULL } 399 }; 400 REGENV *renv; 401 REGINFO *infop; 402 REGION *rp; 403 u_int32_t i; 404 char time_buf[CTIME_BUFLEN]; 405 406 infop = env->reginfo; 407 renv = infop->primary; 408 409 __db_msg(env, "%s", DB_GLOBAL(db_line)); 410 STAT_POINTER("DB_ENV", env->dbenv); 411 __mutex_print_debug_single( 412 env, "ENV handle mutex", env->mtx_env, flags); 413 414 STAT_STRING("Home", env->db_home); 415 __db_prflags(env, NULL, env->open_flags, ofn, NULL, "\tOpen flags"); 416 STAT_FMT("Mode", "%#o", int, env->db_mode); 417 418 STAT_ULONG("Pid cache", env->pid_cache); 419 420 STAT_ISSET("Lockfhp", env->lockfhp); 421 422 STAT_ISSET("Locker", env->env_lref); 423 424 STAT_ISSET("Internal recovery table", env->recover_dtab.int_dispatch); 425 STAT_ULONG("Number of recovery table slots", 426 env->recover_dtab.int_size); 427 STAT_ISSET("External recovery table", env->recover_dtab.ext_dispatch); 428 STAT_ULONG("Number of recovery table slots", 429 env->recover_dtab.ext_size); 430 431 STAT_ULONG("Thread hash buckets", env->thr_nbucket); 432 STAT_ISSET("Thread hash table", env->thr_hashtab); 433 434 STAT_ULONG("Mutex initial count", env->mutex_iq_next); 435 STAT_ULONG("Mutex initial max", env->mutex_iq_max); 436 437 __mutex_print_debug_single( 438 env, "ENV list of DB handles mutex", env->mtx_dblist, flags); 439 STAT_LONG("DB reference count", env->db_ref); 440 441 STAT_ULONG("XA RM ID", env->xa_rmid); 442 443 __mutex_print_debug_single(env, "MT mutex", env->mtx_mt, flags); 444 445 STAT_ISSET("Crypto handle", env->crypto_handle); 446 STAT_ISSET("Lock handle", env->lk_handle); 447 STAT_ISSET("Log handle", env->lg_handle); 448 STAT_ISSET("Cache handle", env->mp_handle); 449 STAT_ISSET("Mutex handle", env->mutex_handle); 450 STAT_ISSET("Replication handle", env->rep_handle); 451 STAT_ISSET("Txn handle", env->tx_handle); 452 453 STAT_ISSET("User copy", env->dbt_usercopy); 454 455 STAT_LONG("Test abort", env->test_abort); 456 STAT_LONG("Test check", env->test_check); 457 STAT_LONG("Test copy", env->test_copy); 458 459 __db_prflags(env, 460 NULL, env->flags, env_fn, NULL, "\tPrivate environment flags"); 461 462 __db_print_reginfo(env, infop, "Primary", flags); 463 __db_msg(env, "%s", DB_GLOBAL(db_line)); 464 __db_msg(env, "Per region database environment information:"); 465 for (rp = R_ADDR(infop, renv->region_off), 466 i = 0; i < renv->region_cnt; ++i, ++rp) { 467 if (rp->id == INVALID_REGION_ID) 468 continue; 469 __db_msg(env, "%s Region:", __reg_type(rp->type)); 470 STAT_LONG("Region ID", rp->id); 471 STAT_LONG("Segment ID", rp->segid); 472 __db_dlbytes(env, 473 "Size", (u_long)0, (u_long)0, (u_long)rp->size); 474 } 475 __db_prflags(env, 476 NULL, renv->init_flags, ofn, NULL, "\tInitialization flags"); 477 STAT_ULONG("Region slots", renv->region_cnt); 478 __db_prflags(env, 479 NULL, renv->flags, regenvfn, NULL, "\tReplication flags"); 480 __db_msg(env, "%.24s\tOperation timestamp", 481 renv->op_timestamp == 0 ? 482 "!Set" : __os_ctime(&renv->op_timestamp, time_buf)); 483 __db_msg(env, "%.24s\tReplication timestamp", 484 renv->rep_timestamp == 0 ? 485 "!Set" : __os_ctime(&renv->rep_timestamp, time_buf)); 486 487 return (0); 488} 489 490static char * 491__env_thread_state_print(state) 492 DB_THREAD_STATE state; 493{ 494 switch (state) { 495 case THREAD_ACTIVE: 496 return ("active"); 497 case THREAD_BLOCKED: 498 return ("blocked"); 499 case THREAD_BLOCKED_DEAD: 500 return ("blocked and dead"); 501 case THREAD_OUT: 502 return ("out"); 503 default: 504 return ("unknown"); 505 } 506 /* NOTREACHED */ 507} 508 509/* 510 * __env_print_thread -- 511 * Display the thread block state. 512 */ 513static int 514__env_print_thread(env) 515 ENV *env; 516{ 517 BH *bhp; 518 DB_ENV *dbenv; 519 DB_HASHTAB *htab; 520 DB_MPOOL *dbmp; 521 DB_THREAD_INFO *ip; 522 PIN_LIST *list, *lp; 523 REGENV *renv; 524 REGINFO *infop; 525 THREAD_INFO *thread; 526 u_int32_t i; 527 char buf[DB_THREADID_STRLEN]; 528 529 dbenv = env->dbenv; 530 531 /* The thread table may not be configured. */ 532 if ((htab = env->thr_hashtab) == NULL) 533 return (0); 534 535 dbmp = env->mp_handle; 536 __db_msg(env, "%s", DB_GLOBAL(db_line)); 537 __db_msg(env, "Thread tracking information"); 538 539 /* Dump out the info we have on thread tracking. */ 540 infop = env->reginfo; 541 renv = infop->primary; 542 thread = R_ADDR(infop, renv->thread_off); 543 STAT_ULONG("Thread blocks allocated", thread->thr_count); 544 STAT_ULONG("Thread allocation threshold", thread->thr_max); 545 STAT_ULONG("Thread hash buckets", thread->thr_nbucket); 546 547 /* Dump out the info we have on active threads. */ 548 __db_msg(env, "Thread status blocks:"); 549 for (i = 0; i < env->thr_nbucket; i++) 550 SH_TAILQ_FOREACH(ip, &htab[i], dbth_links, __db_thread_info) { 551 if (ip->dbth_state == THREAD_SLOT_NOT_IN_USE) 552 continue; 553 __db_msg(env, "\tprocess/thread %s: %s", 554 dbenv->thread_id_string( 555 dbenv, ip->dbth_pid, ip->dbth_tid, buf), 556 __env_thread_state_print(ip->dbth_state)); 557 list = R_ADDR(env->reginfo, ip->dbth_pinlist); 558 for (lp = list; lp < &list[ip->dbth_pinmax]; lp++) { 559 if (lp->b_ref == INVALID_ROFF) 560 continue; 561 bhp = R_ADDR( 562 &dbmp->reginfo[lp->region], lp->b_ref); 563 __db_msg(env, 564 "\t\tpins: %lu", (u_long)bhp->pgno); 565 } 566 } 567 return (0); 568} 569 570/* 571 * __env_print_fh -- 572 * Display statistics for all handles open in this environment. 573 */ 574static int 575__env_print_fh(env) 576 ENV *env; 577{ 578 DB_FH *fhp; 579 580 if (TAILQ_FIRST(&env->fdlist) == NULL) 581 return (0); 582 583 __db_msg(env, "%s", DB_GLOBAL(db_line)); 584 __db_msg(env, "Environment file handle information"); 585 586 MUTEX_LOCK(env, env->mtx_env); 587 588 TAILQ_FOREACH(fhp, &env->fdlist, q) 589 __db_print_fh(env, NULL, fhp, 0); 590 591 MUTEX_UNLOCK(env, env->mtx_env); 592 593 return (0); 594} 595 596/* 597 * __db_print_fh -- 598 * Print out a file handle. 599 * 600 * PUBLIC: void __db_print_fh __P((ENV *, const char *, DB_FH *, u_int32_t)); 601 */ 602void 603__db_print_fh(env, tag, fh, flags) 604 ENV *env; 605 const char *tag; 606 DB_FH *fh; 607 u_int32_t flags; 608{ 609 static const FN fn[] = { 610 { DB_FH_NOSYNC, "DB_FH_NOSYNC" }, 611 { DB_FH_OPENED, "DB_FH_OPENED" }, 612 { DB_FH_UNLINK, "DB_FH_UNLINK" }, 613 { 0, NULL } 614 }; 615 616 if (fh == NULL) { 617 STAT_ISSET(tag, fh); 618 return; 619 } 620 621 STAT_STRING("file-handle.file name", fh->name); 622 623 __mutex_print_debug_single( 624 env, "file-handle.mutex", fh->mtx_fh, flags); 625 626 STAT_LONG("file-handle.reference count", fh->ref); 627 STAT_LONG("file-handle.file descriptor", fh->fd); 628 629 STAT_ULONG("file-handle.page number", fh->pgno); 630 STAT_ULONG("file-handle.page size", fh->pgsize); 631 STAT_ULONG("file-handle.page offset", fh->offset); 632 633 STAT_ULONG("file-handle.seek count", fh->seek_count); 634 STAT_ULONG("file-handle.read count", fh->read_count); 635 STAT_ULONG("file-handle.write count", fh->write_count); 636 637 __db_prflags(env, NULL, fh->flags, fn, NULL, "\tfile-handle.flags"); 638} 639 640/* 641 * __db_print_fileid -- 642 * Print out a file ID. 643 * 644 * PUBLIC: void __db_print_fileid __P((ENV *, u_int8_t *, const char *)); 645 */ 646void 647__db_print_fileid(env, id, suffix) 648 ENV *env; 649 u_int8_t *id; 650 const char *suffix; 651{ 652 DB_MSGBUF mb; 653 int i; 654 655 if (id == NULL) { 656 STAT_ISSET("ID", id); 657 return; 658 } 659 660 DB_MSGBUF_INIT(&mb); 661 for (i = 0; i < DB_FILE_ID_LEN; ++i, ++id) { 662 __db_msgadd(env, &mb, "%x", (u_int)*id); 663 if (i < DB_FILE_ID_LEN - 1) 664 __db_msgadd(env, &mb, " "); 665 } 666 if (suffix != NULL) 667 __db_msgadd(env, &mb, "%s", suffix); 668 DB_MSGBUF_FLUSH(env, &mb); 669} 670 671/* 672 * __db_dl -- 673 * Display a big value. 674 * 675 * PUBLIC: void __db_dl __P((ENV *, const char *, u_long)); 676 */ 677void 678__db_dl(env, msg, value) 679 ENV *env; 680 const char *msg; 681 u_long value; 682{ 683 /* 684 * Two formats: if less than 10 million, display as the number, if 685 * greater than 10 million display as ###M. 686 */ 687 if (value < 10000000) 688 __db_msg(env, "%lu\t%s", value, msg); 689 else 690 __db_msg(env, "%luM\t%s (%lu)", value / 1000000, msg, value); 691} 692 693/* 694 * __db_dl_pct -- 695 * Display a big value, and related percentage. 696 * 697 * PUBLIC: void __db_dl_pct 698 * PUBLIC: __P((ENV *, const char *, u_long, int, const char *)); 699 */ 700void 701__db_dl_pct(env, msg, value, pct, tag) 702 ENV *env; 703 const char *msg, *tag; 704 u_long value; 705 int pct; 706{ 707 DB_MSGBUF mb; 708 709 DB_MSGBUF_INIT(&mb); 710 711 /* 712 * Two formats: if less than 10 million, display as the number, if 713 * greater than 10 million, round it off and display as ###M. 714 */ 715 if (value < 10000000) 716 __db_msgadd(env, &mb, "%lu\t%s", value, msg); 717 else 718 __db_msgadd(env, 719 &mb, "%luM\t%s", (value + 500000) / 1000000, msg); 720 if (tag == NULL) 721 __db_msgadd(env, &mb, " (%d%%)", pct); 722 else 723 __db_msgadd(env, &mb, " (%d%% %s)", pct, tag); 724 725 DB_MSGBUF_FLUSH(env, &mb); 726} 727 728/* 729 * __db_dlbytes -- 730 * Display a big number of bytes. 731 * 732 * PUBLIC: void __db_dlbytes 733 * PUBLIC: __P((ENV *, const char *, u_long, u_long, u_long)); 734 */ 735void 736__db_dlbytes(env, msg, gbytes, mbytes, bytes) 737 ENV *env; 738 const char *msg; 739 u_long gbytes, mbytes, bytes; 740{ 741 DB_MSGBUF mb; 742 const char *sep; 743 744 DB_MSGBUF_INIT(&mb); 745 746 /* Normalize the values. */ 747 while (bytes >= MEGABYTE) { 748 ++mbytes; 749 bytes -= MEGABYTE; 750 } 751 while (mbytes >= GIGABYTE / MEGABYTE) { 752 ++gbytes; 753 mbytes -= GIGABYTE / MEGABYTE; 754 } 755 756 if (gbytes == 0 && mbytes == 0 && bytes == 0) 757 __db_msgadd(env, &mb, "0"); 758 else { 759 sep = ""; 760 if (gbytes > 0) { 761 __db_msgadd(env, &mb, "%luGB", gbytes); 762 sep = " "; 763 } 764 if (mbytes > 0) { 765 __db_msgadd(env, &mb, "%s%luMB", sep, mbytes); 766 sep = " "; 767 } 768 if (bytes >= 1024) { 769 __db_msgadd(env, &mb, "%s%luKB", sep, bytes / 1024); 770 bytes %= 1024; 771 sep = " "; 772 } 773 if (bytes > 0) 774 __db_msgadd(env, &mb, "%s%luB", sep, bytes); 775 } 776 777 __db_msgadd(env, &mb, "\t%s", msg); 778 779 DB_MSGBUF_FLUSH(env, &mb); 780} 781 782/* 783 * __db_print_reginfo -- 784 * Print out underlying shared region information. 785 * 786 * PUBLIC: void __db_print_reginfo 787 * PUBLIC: __P((ENV *, REGINFO *, const char *, u_int32_t)); 788 */ 789void 790__db_print_reginfo(env, infop, s, flags) 791 ENV *env; 792 REGINFO *infop; 793 const char *s; 794 u_int32_t flags; 795{ 796 static const FN fn[] = { 797 { REGION_CREATE, "REGION_CREATE" }, 798 { REGION_CREATE_OK, "REGION_CREATE_OK" }, 799 { REGION_JOIN_OK, "REGION_JOIN_OK" }, 800 { 0, NULL } 801 }; 802 803 __db_msg(env, "%s", DB_GLOBAL(db_line)); 804 __db_msg(env, "%s REGINFO information:", s); 805 STAT_STRING("Region type", __reg_type(infop->type)); 806 STAT_ULONG("Region ID", infop->id); 807 STAT_STRING("Region name", infop->name); 808 STAT_POINTER("Original region address", infop->addr_orig); 809 STAT_POINTER("Region address", infop->addr); 810 STAT_POINTER("Region primary address", infop->primary); 811 STAT_ULONG("Region maximum allocation", infop->max_alloc); 812 STAT_ULONG("Region allocated", infop->allocated); 813 __env_alloc_print(infop, flags); 814 815 __db_prflags(env, NULL, infop->flags, fn, NULL, "\tRegion flags"); 816} 817 818/* 819 * __reg_type -- 820 * Return the region type string. 821 */ 822static const char * 823__reg_type(t) 824 reg_type_t t; 825{ 826 switch (t) { 827 case REGION_TYPE_ENV: 828 return ("Environment"); 829 case REGION_TYPE_LOCK: 830 return ("Lock"); 831 case REGION_TYPE_LOG: 832 return ("Log"); 833 case REGION_TYPE_MPOOL: 834 return ("Mpool"); 835 case REGION_TYPE_MUTEX: 836 return ("Mutex"); 837 case REGION_TYPE_TXN: 838 return ("Transaction"); 839 case INVALID_REGION_TYPE: 840 return ("Invalid"); 841 } 842 return ("Unknown"); 843} 844 845#else /* !HAVE_STATISTICS */ 846 847/* 848 * __db_stat_not_built -- 849 * Common error routine when library not built with statistics. 850 * 851 * PUBLIC: int __db_stat_not_built __P((ENV *)); 852 */ 853int 854__db_stat_not_built(env) 855 ENV *env; 856{ 857 __db_errx(env, "Library build did not include statistics support"); 858 return (DB_OPNOTSUP); 859} 860 861int 862__env_stat_print_pp(dbenv, flags) 863 DB_ENV *dbenv; 864 u_int32_t flags; 865{ 866 COMPQUIET(flags, 0); 867 868 return (__db_stat_not_built(dbenv->env)); 869} 870#endif 871